用groupby传入列表可实现多维度聚合,需注意列名顺序、NaN默认被丢弃(dropna=False可保留)、禁用逗号传参而必须用列表,聚合函数类型决定返回Series或DataFrame,agg字典形式必返DataFrame。

直接说结论:用 groupby 传入列表即可实现多维度聚合,但必须注意列名顺序、缺失值处理和聚合函数的返回类型是否对齐。
多列分组的写法和常见错误
最常用的方式是把多个列名放进一个列表传给 groupby,比如按地区和年份统计销量:df.groupby(['region', 'year'])['sales'].sum()。这里不是字符串拼接,也不是用逗号分隔的参数,必须是列表。
容易踩的坑:
- 列名写错或大小写不一致,报
KeyError—— 建议先用df.columns.tolist()确认真实列名 - 某列含
NaN,默认会被丢弃(dropna=True)—— 若需保留空组,加参数dropna=False - 误写成
groupby('col1', 'col2'),会触发TypeError: unhashable type,因为第二个参数被当成axis
不同聚合方式对结果结构的影响
聚合函数决定输出是 Series 还是 DataFrame,也影响索引层级:
-
df.groupby(['A', 'B'])['C'].sum()→ 返回Series,索引是MultiIndex(两层) -
df.groupby(['A', 'B']).sum()→ 对所有数值列求和,返回DataFrame,列保持原名 -
df.groupby(['A', 'B']).agg({'C': 'sum', 'D': ['mean', 'std']})→ 返回带多级列名的DataFrame,列名为MultiIndex
注意:一旦用了字典形式的 agg,哪怕只针对一列,返回值也是 DataFrame,不是 Series。
性能与内存敏感场景下的建议
多维分组本身不慢,但后续操作容易拖慢整体流程:
- 避免在
groupby后链式调用多个apply—— 每次都重建分组对象,改用单次agg或自定义函数内完成全部逻辑 - 如果分组键组合太多(比如上百万种唯一组合),
groupby可能爆内存 —— 先用value_counts(['A','B'])快速探查分布,再决定是否采样或过滤 -
as_index=False能省去后续reset_index(),尤其在管道中连续操作时更干净
真正麻烦的是嵌套聚合逻辑(比如“每组内 top3 的均值”),这时 apply 不可避免,但记得加 include_groups=False 避免意外传入分组键列;另外,groupby 的分组键顺序会影响 MultiIndex 层级顺序,而这个顺序会传导到后续的 unstack 或 pivot 行为里——很多人调试半天才发现是键顺序反了。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











