groupby后agg()只返回一列是因为默认对数值列调用numpy.mean并跳过非数值列;需显式指定列或用字典映射函数,多级聚合列名需手动展平,条件计数应使用eq()或手动计算避免NaN问题。

groupby 后直接用 agg() 为什么只返回一列?
因为没传聚合函数列表或字典,agg() 默认对每列调用 numpy.mean,但若原始 DataFrame 里有非数值列(比如字符串 ID),pandas 会静默跳过它们,导致结果列数变少——这不是 bug,是默认行为。
- 显式指定要聚合的列:
df.groupby('category')[['sales', 'profit']].agg('sum') - 想保留非数值列并做特定聚合(如取首值):
.agg({'sales': 'sum', 'name': 'first'}) - 避免隐式类型推断:分组前先确认
df.dtypes,把本该是数值却读成object的列用pd.to_numeric(..., errors='coerce')清洗
agg() 里混用多种统计方式(均值、最大值、计数)怎么写才不报错?
必须用字典映射列名到函数,不能直接传函数列表——否则 pandas 会对所有列重复应用同一套函数,容易因类型不匹配崩在 max 或 count 上。
- 正确写法:
.agg({'price': ['mean', 'max'], 'id': 'count', 'status': pd.Series.nunique}) - 函数名用字符串(如
'mean')更安全;自定义函数需确保能处理空组(返回标量,别返回 Series) - 注意
'count'和'size'区别:count忽略 NaN,size统计行数(含 NaN)
多级分组 + 多指标聚合后,索引乱了怎么还原成扁平列名?
groupby 多列 + agg 多函数后,列名自动变成 MultiIndex,导出 Excel 或给下游用时经常被当成“结构异常”。不用重置索引再 rename,有更直接的办法。
- 一步展平:
result.columns = ['_'.join(col).strip() for col in result.columns.values] - 如果只想展平部分层级(比如只合并函数名和字段名):
result.columns.map('_'.join) - 警惕
as_index=False只影响行索引,对列名没用;reset_index()是行操作,不是列名修复手段
用 agg() 做条件计数(比如“好评率”)为什么结果全是 NaN?
常见于写 agg({'review': lambda x: (x == 'good').mean()}) 却忘了 x 是 Series,而 .mean() 对布尔值有效——但若 review 列含空值或非预期字符串,x == 'good' 会产生布尔数组加 NaN,mean() 默认跳过 NaN,可结果仍可能为 NaN(比如全 NaN)。
- 稳妥写法:
lambda x: (x == 'good').sum() / len(x)(手动算,不依赖自动跳过) - 更推荐用
agg({'review': lambda x: x.eq('good').mean()}),eq()比==对 NaN 更鲁棒 - 性能提示:避免在
agg里反复调用len(x)或x.count(),pandas 内部已缓存组大小,可用__len__或提前计算

















