13  Pandas groupby用法

13.1 引言分组聚合的分析价值

Split-Apply-Combine(分组-应用-合并)是数据分析的核心范式: 1. Split: 将数据分为多个组 2. Apply: 对每组应用函数 3. Combine: 合并结果

金融应用场景: - 按行业统计股票表现 - 按时间段计算收益率 - 按市场分组分析风险

13.2 groupby基础

列表 13.1
# ⚠️ 平台原始代码 - 请原样输入至教学平台(注释除外),平台才会判定答案正确
import pandas as pd  # 导入Pandas数据分析库
df = pd.DataFrame({'A' : ['foo', 'bar', 'foo', 'bar',  # 创建数据框df
             'foo', 'bar'],  # A列分组标签的续行数据
          'B' : ['one', 'one', 'two', 'three',  # "B"的数据序列
             'two', 'two'],  # B列分组标签的续行数据
          'C' : [1, 5, 5, 2, 5, 5],  # "C"的数据序列
          'D' : [2.0, 5., 8., 1., 2., 9.]})  # "D"的数据序列
grouped = df.groupby('A')[['C', 'D']]  # 按指定列分组聚合
result=grouped.transform(lambda x: (x - x.mean()) / x.std())  # 定义匿名函数result
print(result)  # 输出分析结果数据

13.3 聚合函数(Aggregation)

列表 13.2
# =============================================================================
# 题目:分组聚合统计
# =============================================================================
# 本示例演示对分组数据应用常用聚合函数
# 金融应用:计算每只股票的平均收益率、每行业的总市值等

# ==================== 选择特定列分组 ====================
# 只对C、D两列进行分组聚合(排除不需要的列)
grouped = df.groupby('A')[['C', 'D']]  # 双重索引选择特定列

# ==================== 应用聚合函数 ====================
# 计算每组的均值
print("均值:")
print(grouped.mean())  # mean()返回每组的平均值,NaN会被自动忽略

# 计算每组的总和
print(f"\n求和:")
print(grouped.sum())  # sum()返回每组的总和

# 计算每组的非缺失值计数
print(f"\n计数:")
print(grouped.count())  # count()统计每组的非空值数量

# 计算每组的标准差
print(f"\n标准差:")
print(grouped.std())  # std()计算标准差,衡量数据波动性

# ==================== 同时应用多个聚合函数 ====================
# 对每列应用多个统计函数
print(f"\n自定义统计:")
print(grouped.agg(['mean', 'std', 'min', 'max']))
# agg()可接收函数列表,同时计算均值、标准差、最小值、最大值

13.4 transform转换操作

transform返回与原数据相同形状的结果。

列表 13.3
# =============================================================================
# 题目:分组标准化转换
# =============================================================================
# 本示例演示使用transform进行组内标准化
# 金融应用:消除不同股票的价格量纲差异,便于比较

# ==================== 标准化转换 ====================
# 标准化公式: (x - mean) / std
# 将每组数据转换为均值为0、标准差为1的分布
result = grouped.transform(lambda x: (x - x.mean()) / x.std())
# transform()对每组应用函数,返回与原数据形状相同的DataFrame
# lambda x是匿名函数,x代表每组的数据

print("标准化结果:")
print(result)  # 输出:原数据被标准化,但形状保持不变

# ==================== 验证标准化结果 ====================
# 验证:每组的均值应约等于0,标准差应约等于1
print(f"\n验证-每组均值:")
print(result.groupby(df['A']).mean())
# 对标准化后的数据再分组计算均值,应接近0

print(f"\n验证-每组标准差:")
print(result.groupby(df['A']).std())
# 对标准化后的数据再分组计算标准差,应接近1

金融应用: 组内标准化,消除组间差异

13.5 filter过滤分组

列表 13.4
# =============================================================================
# 题目:按条件过滤分组
# =============================================================================
# 本示例演示如何基于组的统计特征过滤整个组
# 金融应用:筛选出交易量活跃的股票、过滤掉小客户群体

# ==================== 过滤分组 ====================
# 保留C列均值>3的整个组(不是过滤行,是过滤组)
filtered = df.groupby('A').filter(lambda x: x['C'].mean() > 3)
# filter()对每组应用条件函数,返回满足条件的组的所有行
# 逻辑:如果某组的C列平均值>3,则保留该组的所有数据

print("过滤后的数据:")
print(filtered)  # 输出:只包含C列均值>3的组的数据

13.6 apply灵活应用

列表 13.5
# =============================================================================
# 题目:对每组应用复杂自定义函数
# =============================================================================
# 本示例演示使用apply实现灵活的分组操作
# 金融应用:找出每只股票价格最高的交易日、计算每组的复合增长率等

# ==================== 定义自定义函数 ====================
# 自定义函数:找出每组D列最大的行
def get_max_row(group):
    """找出分组中D列最大的行"""
    return group.loc[group['D'].idxmax()]
# group是每组的完整DataFrame
# idxmax()返回D列最大值的索引(行号)
# loc[]根据索引定位整行数据

# ==================== 对每组应用自定义函数 ====================
result = df.groupby('A').apply(get_max_row)
# apply()对每组应用自定义函数,可返回任意结构的DataFrame
print("每组D列最大的行:")
print(result)  # 输出:每个组中D列最大的那一行数据