|

Pandas 常用函数详解

Pandas 常用函数详解

1. 数据创建和查看函数

1.1 创建数据

import pandas as pd
import numpy as np

# 从各种数据源创建
df_dict = pd.DataFrame({
    'A': [1, 2, 3, 4],
    'B': [10, 20, 30, 40],
    'C': ['a', 'b', 'c', 'd']
})

# 空DataFrame
df_empty = pd.DataFrame(columns=['col1', 'col2'])

# 指定索引
df_indexed = pd.DataFrame(df_dict, index=['w', 'x', 'y', 'z'])

# 从Series创建
s = pd.Series([1, 2, 3])
df_from_series = pd.DataFrame({'col': s})

# 生成测试数据
dates = pd.date_range('20230101', periods=6)
df_test = pd.DataFrame(np.random.randn(6, 4), 
                      index=dates, 
                      columns=list('ABCD'))

1.2 数据查看

# 基本查看
print(df.head(3))        # 前3行
print(df.tail(2))        # 后2行
print(df.sample(5))      # 随机5行
print(df.info())         # 数据信息
print(df.describe())     # 描述性统计

# 形状和结构
print(df.shape)          # (行, 列)
print(df.columns)        # 列名
print(df.index)          # 索引
print(df.dtypes)         # 数据类型
print(df.values)         # 底层numpy数组

# 转置
print(df.T)

# 内存使用
print(df.memory_usage(deep=True))

2. 选择和索引函数

2.1 基本选择

# 列选择
col_series = df['A']              # 单列(Series)
col_df = df[['A', 'B']]           # 多列(DataFrame)
df['new_col'] = df['A'] + df['B'] # 新列

# 行选择
first_row = df.iloc[0]            # 位置索引
labeled_row = df.loc['w']         # 标签索引
rows_slice = df.iloc[1:3]         # 切片
specific_rows = df.loc[['w', 'y']]

# 混合选择
subset = df.loc['w':'y', ['A', 'C']]     # 行标签+列标签
pos_subset = df.iloc[0:2, [0, 2]]        # 位置+位置

2.2 条件选择

# 布尔索引
high_a = df[df['A'] > 0]
not_null = df[df['B'].notnull()]
multiple = df[(df['A'] > 0) & (df['B'] < 20)]

# isin方法
in_values = df[df['C'].isin(['a', 'c'])]
not_in = df[~df['C'].isin(['b', 'd'])]

# query方法(字符串条件)
result = df.query('A > 0 and B < 20')
result2 = df.query('A > @threshold')  # 使用变量

# between方法
in_range = df[df['A'].between(1, 3)]

# 字符串条件
string_cond = df[df['C'].str.startswith('a')]

2.3 高级索引

# 多级索引
arrays = [np.array(['A', 'A', 'B', 'B']), np.array(['one', 'two', 'one', 'two'])]
index = pd.MultiIndex.from_arrays(arrays, names=('first', 'second'))
df_multi = pd.DataFrame(np.random.randn(4, 2), index=index, columns=['X', 'Y'])

# 多级索引操作
print(df_multi.loc['A'])           # 选择第一级
print(df_multi.loc[('A', 'one')])  # 具体组合
print(df_multi.xs('one', level=1)) # 交叉截面

# stack和unstack
stacked = df_multi.stack()
unstacked = stacked.unstack()

3. 数据操作函数

3.1 添加和删除

# 添加列
df['A_squared'] = df['A'] ** 2
df['category'] = pd.cut(df['A'], bins=3)  # 分箱
df.assign(new_col=lambda x: x['A'] * 2)   # 非原地

# 添加行
new_row = pd.DataFrame({'A': [5], 'B': [50], 'C': ['e']}, index=['new'])
df_appended = pd.concat([df, new_row])

# 删除
df_dropped_cols = df.drop(['A_squared'], axis=1)
df_dropped_rows = df.drop(['w'], axis=0)
df_popped = df.pop('C')  # 返回删除的列(Series)

# 重命名
df_renamed = df.rename(columns={'A': 'value1', 'B': 'value2'})
df_index_renamed = df.rename(index={'w': 'row1'})

3.2 排序

# 按值排序
df_sorted_values = df.sort_values('A', ascending=False)
df_multi_sort = df.sort_values(['A', 'B'], ascending=[True, False])

# 按索引排序
df_sorted_index = df.sort_index(ascending=False)
df_sorted_both = df.sort_index(axis=1).sort_index(axis=0)

# 稳定排序
df_stable = df.sort_values('A', kind='stable')

4. 缺失值处理函数

# 检测
has_missing = df.isnull().any().any()
missing_count = df.isnull().sum()
missing_rate = df.isnull().mean()

# 填充
df_filled_mean = df.fillna(df.mean(numeric_only=True))
df_filled_forward = df.fillna(method='ffill')
df_filled_value = df.fillna({'A': 0, 'B': 'missing'})

# 高级填充
df_group_filled = df.groupby('category')['A'].fillna(
    df.groupby('category')['A'].transform('mean')
)

# 插值
df_interpolated = df.interpolate(method='linear')
time_interpolated = df.interpolate(method='time')  # 需要DatetimeIndex

# 删除
df_dropped = df.dropna()
df_thresh = df.dropna(thresh=3)  # 至少3个非空值
df_subset_drop = df.dropna(subset=['A', 'B'])

5. 字符串操作函数

# 字符串方法(.str访问器)
df['C_upper'] = df['C'].str.upper()
df['C_length'] = df['C'].str.len()
df['C_contains'] = df['C'].str.contains('a')
df['C_replace'] = df['C'].str.replace('a', 'A')
df['C_split'] = df['C'].str.split('').str[0]  # 错误,应使用expand=True

# 提取和匹配
df['first_letter'] = df['C'].str[0]
df['pattern'] = df['C'].str.extract(r'([a-z])')
df['match'] = df['C'].str.match(r'^a')

# 高级字符串操作
df['padded'] = df['C'].str.zfill(3)  # 补零
df['title_case'] = df['C'].str.title()
df['words'] = df['description'].str.split(expand=True)  # 分词到列

# 正则表达式
df['phone_clean'] = df['phone'].str.replace(r'[^\d+]', '', regex=True)
df['email_domain'] = df['email'].str.extract(r'@([\w.-]+)', expand=False)

6. 合并和连接函数

6.1 连接(concat)

# 行连接
df1 = pd.DataFrame({'A': [1, 2], 'B': [3, 4]})
df2 = pd.DataFrame({'A': [5, 6], 'B': [7, 8]})
concat_rows = pd.concat([df1, df2], ignore_index=True)

# 列连接
concat_cols = pd.concat([df1, df2], axis=1)

# 多级索引连接
concat_keys = pd.concat([df1, df2], keys=['x', 'y'])

# 内连接列
concat_inner = pd.concat([df1, df2], axis=1, join='inner')

6.2 合并(merge)

# 基本合并
left = pd.DataFrame({'key': ['K0', 'K1'], 'A': [1, 2]})
right = pd.DataFrame({'key': ['K0', 'K2'], 'B': [3, 4]})

# 内连接
merged_inner = pd.merge(left, right, on='key', how='inner')

# 左连接
merged_left = pd.merge(left, right, on='key', how='left')

# 多键合并
df1 = pd.DataFrame({'lkey': ['a', 'b'], 'value': [1, 2]})
df2 = pd.DataFrame({'rkey': ['a', 'c'], 'value': [3, 4]})
merged_multi = pd.merge(df1, df2, left_on='lkey', right_on='rkey')

# 指标前缀
merged_prefix = pd.merge(left, right, on='key', suffixes=('_left', '_right'))

6.3 连接(join)

# 基于索引连接
left_idx = left.set_index('key')
right_idx = right.set_index('key')
joined = left_idx.join(right_idx, how='inner')

# 多表连接
df1_idx = df1.set_index('id')
df2_idx = df2.set_index('id')
df3_idx = df3.set_index('id')
result = df1_idx.join([df2_idx, df3_idx], how='outer')

7. 分组和聚合函数

7.1 基本分组

df_group = pd.DataFrame({
    'category': ['A', 'A', 'B', 'B', 'A'],
    'value1': [1, 2, 3, 4, 5],
    'value2': [10, 20, 30, 40, 50]
})

# 基本分组
grouped = df_group.groupby('category')
print(grouped.groups)  # 分组信息
print(grouped.size())  # 每组大小

# 聚合
mean_vals = grouped.mean()
sum_vals = grouped['value1'].sum()

7.2 多函数聚合

# 多个聚合函数
agg_result = grouped.agg({
    'value1': ['sum', 'mean', 'std'],
    'value2': ['min', 'max']
})

# 重命名结果
agg_named = grouped.agg(
    value1_sum=('value1', 'sum'),
    value1_mean=('value1', 'mean'),
    value2_max=('value2', 'max')
)

# 自定义聚合
def range_func(x):
    return x.max() - x.min()

custom_agg = grouped.agg({
    'value1': ['sum', range_func],
    'value2': 'count'
})

7.3 分组转换和过滤

# transform(保持形状)
df['value1_rank'] = grouped['value1'].transform('rank')
df['value1_mean'] = grouped['value1'].transform('mean')

# filter(筛选组)
def filter_large(group):
    return len(group) >= 2

filtered = grouped.filter(filter_large)

# apply(灵活操作)
def summarize(group):
    return pd.DataFrame({
        'count': len(group),
        'mean': group['value1'].mean()
    })

applied = grouped.apply(summarize)

8. 重塑函数

8.1 透视表

# 简单透视
pivot_simple = df.pivot(index='date', columns='category', values='value')

# 聚合透视
pivot_table = df.pivot_table(values='value', 
                            index='date', 
                            columns='category',
                            aggfunc='sum',
                            fill_value=0,
                            margins=True)  # 添加总计

# 多级透视
pivot_multi = df.pivot_table(values='sales', 
                            index=['region', 'product'],
                            columns='year',
                            aggfunc='sum')

8.2 melt和wide_to_long

# 宽格式转长格式
wide_df = pd.DataFrame({
    'id': [1, 2],
    'year_2021': [100, 200],
    'year_2022': [150, 250]
})

long_df = pd.melt(wide_df, 
                 id_vars=['id'],
                 value_vars=['year_2021', 'year_2022'],
                 var_name='year',
                 value_name='sales')

# 自动识别
long_auto = pd.wide_to_long(wide_df, 
                           stubnames='year',
                           i='id',
                           j='year_type',
                           sep='_',
                           suffix='\d+')

8.3 stack和unstack

# 多级索引
multi_idx = pd.MultiIndex.from_product([['A', 'B'], ['X', 'Y']])
df_multi = pd.DataFrame(np.random.randn(4, 4), 
                       index=multi_idx, 
                       columns=['P', 'Q', 'R', 'S'])

# stack(列转行)
stacked = df_multi.stack()
double_stacked = df_multi.stack([0, 1])

# unstack(行转列)
unstacked = stacked.unstack()
partial_unstack = stacked.unstack(0)  # 指定级别

9. 统计函数

9.1 描述性统计

# 基本统计
print(df.mean())          # 均值
print(df.median())        # 中位数
print(df.std())           # 标准差
print(df.var())           # 方差
print(df.min())           # 最小值
print(df.max())           # 最大值
print(df.sum())           # 总和
print(df.count())         # 非空计数
print(df.quantile([0.25, 0.5, 0.75]))  # 分位数

# 相关性
corr_matrix = df.corr()   # 相关系数矩阵
corr_pairs = df.corrwith(df['A'])  # 与A的相关性

# 协方差
cov_matrix = df.cov()

9.2 滚动统计

# 需要时间索引或数值索引
df_time = df_test.copy()
df_time.index = pd.date_range('2023-01-01', periods=6, freq='D')

# 滚动窗口
rolling_mean = df_time['A'].rolling(window=3).mean()
rolling_sum = df_time['A'].rolling(window=3, min_periods=1).sum()

# 扩展窗口
expanding_mean = df_time['A'].expanding().mean()
expanding_max = df_time['A'].expanding(min_periods=2).max()

# 自定义窗口
custom_window = df_time['A'].rolling('2D').mean()  # 时间窗口

9.3 排名和分位

# 排名
df['A_rank'] = df['A'].rank()                    # 升序排名
df['A_rank_desc'] = df['A'].rank(ascending=False) # 降序排名
df['dense_rank'] = df['A'].rank(method='dense')  # 密集排名
df['min_rank'] = df['A'].rank(method='min')      # 最小排名

# 分位数
df['A_quantile'] = pd.qcut(df['A'], q=4, labels=['Q1', 'Q2', 'Q3', 'Q4'])
df['A_percentile'] = df['A'].rank(pct=True)  # 百分位排名

10. 时间序列函数

# 创建时间索引
dates = pd.date_range('2023-01-01', periods=100, freq='D')
ts_df = pd.DataFrame(np.random.randn(100, 2), 
                    index=dates, 
                    columns=['A', 'B'])

# 时间属性
ts_df['year'] = ts_df.index.year
ts_df['month'] = ts_df.index.month
ts_df['weekday'] = ts_df.index.day_name()
ts_df['quarter'] = ts_df.index.quarter

# 重采样
monthly = ts_df.resample('M').mean()
quarterly = ts_df.resample('Q').sum()

# 移位和滞后
ts_df['A_lag1'] = ts_df['A'].shift(1)
ts_df['A_lead1'] = ts_df['A'].shift(-1)
ts_df['A_diff'] = ts_df['A'].diff()      # 一阶差分
ts_df['A_pct'] = ts_df['A'].pct_change() # 变化率

# 滚动时间窗口
weekly_rolling = ts_df['A'].rolling('7D').mean()
monthly_rolling = ts_df['A'].rolling('30D').sum()

11. 输入输出函数

11.1 CSV操作

# 读取
df_csv = pd.read_csv('data.csv', 
                    encoding='utf-8',
                    parse_dates=['date'],
                    dtype={'id': 'int32', 'category': 'category'})

# 写入
df_csv.to_csv('output.csv', 
             index=False,
             encoding='utf-8',
             date_format='%Y-%m-%d')

11.2 Excel操作

# 读取
df_excel = pd.read_excel('data.xlsx', 
                        sheet_name='Sheet1',
                        usecols='A:C')

# 多工作表写入
with pd.ExcelWriter('output.xlsx') as writer:
    df1.to_excel(writer, sheet_name='数据1', index=False)
    df2.to_excel(writer, sheet_name='数据2', index=False)

11.3 其他格式

# JSON
df.to_json('data.json', orient='records', indent=2)
df_json = pd.read_json('data.json')

# SQL
from sqlalchemy import create_engine
engine = create_engine('sqlite:///database.db')
df.to_sql('table_name', engine, if_exists='replace')
df_sql = pd.read_sql('SELECT * FROM table_name', engine)

# Pickle(二进制)
df.to_pickle('data.pkl')
df_pickle = pd.read_pickle('data.pkl')

# Parquet(高效列式存储)
df.to_parquet('data.parquet', compression='snappy')
df_parquet = pd.read_parquet('data.parquet')

12. 实用工具函数

12.1 数据转换

# 数值转换
pd.to_numeric(df['col'], errors='coerce')  # 字符串转数值
pd.to_datetime(df['date'], format='%Y-%m-%d')  # 字符串转日期

# 类别转换
pd.Categorical(df['col'])  # 分类类型
pd.get_dummies(df['category'], prefix='cat')  # 独热编码

# 标准化/归一化
from sklearn.preprocessing import StandardScaler, MinMaxScaler
scaler = StandardScaler()
df['A_scaled'] = scaler.fit_transform(df[['A']])

# 字符串处理
pd.Series(['apple', 'banana']).str.lower()
pd.Series(['a,b,c']).str.split(',').str[0]

12.2 实用函数

# 唯一值和频数
print(df['C'].unique())
print(df['C'].nunique())
print(df['C'].value_counts())

# 查找位置
print(df['A'].idxmax())  # 最大值位置
print(df['A'].idxmin())  # 最小值位置

# 剪切和限制
df['A_clipped'] = df['A'].clip(lower=0, upper=10)

# 取样
df_sample = df.sample(frac=0.1, random_state=42)  # 10%样本
df_sample_n = df.sample(n=5, replace=True)        # 有放回抽样

# 连接字符串
pd.concat([s1, s2], axis=1)  # 列连接
s1.combine(s2, lambda x1, x2: x1 if pd.notna(x1) else x2)  # 组合

12.3 性能和诊断

# 性能分析
%timeit df['A'].mean()  # Jupyter时间测试

# 内存优化
df_optimized = df.copy()
for col in df.select_dtypes(['object']).columns:
    if df[col].nunique() < len(df) * 0.5:
        df_optimized[col] = df[col].astype('category')

# 进度条(大操作)
from tqdm import tqdm
tqdm.pandas()
df['processed'] = df['text'].progress_apply(lambda x: x.upper())

# 复制和视图
df_copy = df.copy(deep=True)    # 深拷贝
df_view = df[:]                 # 浅拷贝/视图

13. 实际应用组合示例

# 完整数据处理流程
def complete_data_pipeline(df):
    """完整的数据处理示例"""

    # 1. 数据清洗
    df_clean = df.dropna(thresh=len(df.columns)*0.8)
    df_clean = df_clean.drop_duplicates()

    # 2. 类型转换
    numeric_cols = df_clean.select_dtypes(include=['object']).columns
    for col in numeric_cols:
        df_clean[col] = pd.to_numeric(df_clean[col], errors='coerce')

    # 3. 创建特征
    if 'date' in df_clean.columns:
        df_clean['year'] = pd.to_datetime(df_clean['date']).dt.year
        df_clean['month'] = pd.to_datetime(df_clean['date']).dt.month

    # 4. 分组统计
    if 'category' in df_clean.columns:
        group_stats = df_clean.groupby('category').agg({
            'value': ['mean', 'sum', 'count']
        })
        group_stats.columns = ['mean_value', 'sum_value', 'count']

    # 5. 透视分析
    pivot = df_clean.pivot_table(values='value', 
                                index='category', 
                                columns='year', 
                                aggfunc='sum')

    # 6. 排名和分位
    df_clean['value_rank'] = df_clean['value'].rank()
    df_clean['value_quantile'] = pd.qcut(df_clean['value'], q=4)

    return df_clean, group_stats, pivot

# 使用
df_processed, stats, pivot = complete_data_pipeline(df)

14. 调试和最佳实践

14.1 常见模式

# 链式操作
result = (df
         .query('A > 0')
         .groupby('category')
         .agg({'B': 'mean'})
         .reset_index()
         .sort_values('B', ascending=False))

# 方法链最佳实践
(df.pipe(lambda x: x.dropna())
   .assign(new_col=lambda x: x['A'] * 2)
   .query('new_col > 10')
)

# 错误处理
try:
    result = df.groupby('nonexistent_col').mean()
except KeyError as e:
    print(f"列不存在: {e}")
    # 处理逻辑

14.2 性能提示

# 避免
for i in range(len(df)):
    df.iloc[i] = some_calculation()

# 推荐
df['new_col'] = df['A'].apply(some_calculation)  # 仍然较慢
df['new_col'] = np.where(df['A'] > 0, df['A']*2, 0)  # 向量化

# 大数据处理
def process_chunks(file_path, func, chunk_size=10000):
    chunks = []
    for chunk in pd.read_csv(file_path, chunksize=chunk_size):
        processed = func(chunk)
        chunks.append(processed)
    return pd.concat(chunks, ignore_index=True)

这些常用函数构成了Pandas的核心能力,熟练掌握它们可以处理绝大多数数据分析任务。建议结合实际项目练习,理解每个函数的适用场景和性能特性。

类似文章

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注