groupby后用agg()传入自定义函数即可,函数须接收series、返回标量;多列不同聚合用字典指定列名与函数;需整组dataframe时改用apply();返回series会生成multiindex,可用namedagg或reset_index()调整。

groupby 后怎么传入自定义函数做聚合?
直接把函数名传给 agg() 就行,但要注意函数接收的是 Series(不是 DataFrame),返回标量值。比如想对每组计算“最大值与最小值的差”,写成 lambda x: x.max() - x.min() 或单独定义函数。
常见错误是函数里用了 df['col'] 这种写法——groupby 拆出来的每组只是单列 Series,没有列名索引。另外,如果函数返回非标量(如 list、Series),agg() 会报 ValueError: Function does not reduce。
- 正确:
df.groupby('category')['value'].agg(lambda x: x.std() / x.mean()) - 错误:
df.groupby('category').agg(lambda x: x['value'].sum())(x 是 Series,没['value']) - 错误:
df.groupby('category')['value'].agg(lambda x: x.tolist())(返回 list,不满足 reduce 要求)
多个字段用不同自定义函数聚合怎么写?
用字典传参,键是列名,值是函数或函数列表。注意:键必须是原始 DataFrame 中存在的列名,不能是新生成的列;函数仍作用于每组的该列 Series。
如果某列要同时用多个函数(比如均值和中位数),值可以是列表,如 [np.mean, np.median];如果只想用一个自定义函数,就写单个函数对象或 lambda。
- 合法:
df.groupby('group')[['A', 'B']].agg({'A': lambda x: x.quantile(0.9), 'B': 'sum'}) - 非法:
df.groupby('group').agg({'C': lambda x: x.max()})(列 C 不存在) - 注意:结果列名会变成多级索引,可用
as_index=False或reset_index()平展
自定义函数里需要访问整组 DataFrame 怎么办?
agg() 不支持,得换用 apply()。它把每组当作子 DataFrame 传入,函数可任意操作,但性能明显下降,且返回结果形状更难控制。
典型场景:计算组内某列相对于组均值的偏差比例,或做跨列运算(比如用 A 列除以 B 列再求和)。这时必须用 apply(),且函数返回必须是标量、Series 或 DataFrame,否则容易出错。
- 推荐:
df.groupby('group').apply(lambda g: (g['A'] / g['B']).sum()) - 危险:
df.groupby('group').apply(lambda g: g[['A','B']].corr())(返回 DataFrame,结果维度爆炸) - 性能提示:
apply()是 Python 层循环,大数据量时比agg()慢数倍,能用agg()就别用apply()
为什么自定义聚合后结果索引变乱了?
默认情况下,groupby().agg() 保留分组键作为结果的索引;但如果传入的函数返回的是 Series(比如 lambda x: pd.Series({'min': x.min(), 'max': x.max()})),结果会自动升维成 MultiIndex,列名变成函数返回的 index 值。
这不是 bug,而是 Pandas 的设计逻辑:返回 Series → 视为多输出 → 自动拼接列名。若想避免,要么改用字典方式分别定义各输出,要么用 pd.NamedAgg(Pandas 0.25+)显式命名:
- 混乱写法:
df.groupby('x')['y'].agg(lambda x: pd.Series([x.min(), x.max()], index=['lo','hi'])) - 清晰写法:
df.groupby('x').agg(lo=('y', 'min'), hi=('y', 'max')) - 兼容旧版:加
as_index=False或后续调用reset_index()
真正容易被忽略的是:当函数内部修改了输入 Series 的 index(比如重设、切片),agg() 可能静默丢掉部分数据或报错,调试时建议先在单组上手动测试函数行为。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











