groupby本质是分组迭代而非魔法表格操作,返回懒加载的groupby对象;需调用聚合方法才执行计算,且分组键须严格对齐索引、处理nan及dtype一致性。

groupby 本质是分组迭代,不是魔法表格操作
Python 的 groupby(来自 pandas)不会自动“整理好数据等你算”,它只是按键把行划成若干个懒加载的迭代器。你一不调用聚合方法(如 .sum()、.mean()),它就啥也不干;你一调用,它才真正遍历每组数据——这意味着:没重置索引、没处理缺失值、没确认分组键唯一性时,结果可能和直觉差很远。
-
groupby返回的是GroupBy对象,不是DataFrame,不能直接打印出整齐表格 - 分组键含
NaN时,默认被排除(不报错,但静默丢弃),得加dropna=False才保留 - 若分组键是列表或数组,长度必须和 DataFrame 行数一致,否则抛
ValueError: Grouper and axis must be same length
分组键必须对齐索引,否则 groupby 会“看错行”
常见错误是拿一个外部 list 当分组键,但它的顺序/长度和原始 DataFrame 不一致——比如从另一份 CSV 里读出来的标签顺序乱了,或者用了切片后没重置索引。这时 groupby 会按位置硬对齐,导致 A 组里混进 B 的数据。
- 安全做法:用 DataFrame 内部列(
df['category'])或明确构造的pd.Series,并确保其index和df.index完全一致 - 检查手段:
df.index.equals(other_series.index),别只看len() - 容易踩坑:用
df.iloc[:100]['label']做分组键 → 索引还是原样,但只取了前 100 行,后续 groupby 会广播或报错
agg() 里传函数名和传函数对象行为不同
写 .agg('mean') 和 .agg(np.mean) 看似一样,实际触发路径不同:前者走 pandas 内置优化路径,支持字符串别名(如 'first'、'nunique'),后者走通用 Python 函数调用,能传自定义逻辑但更慢,且对返回值形状更敏感。
-
.agg(['mean', 'std'])→ 返回多列,列名带统计名;.agg([np.mean, np.std])→ 列名是函数名(如<function numpy.mean></function>),难读 - 传 lambda 时注意:lambda 接收的是 Series,不是单个值,别写成
lambda x: x > 0.5(返回布尔 Series,agg 会报错) - 混合类型聚合(如数值列用
mean,字符列用'first')必须用字典:.agg({'price': 'mean', 'name': 'first'})
多级 groupby 的键顺序影响结果结构
写 df.groupby(['A', 'B']) 和 df.groupby(['B', 'A']) 分组内容一样,但结果的索引层级顺序相反,直接影响 .unstack()、.xs() 或后续切片逻辑。
立即学习“Python免费学习笔记(深入)”;
- 默认生成
MultiIndex,第一级是第一个键('A'),第二级是第二个键('B') - 如果之后要
.unstack('B'),那'B'必须是内层索引;否则得先.swaplevel()或用.reorder_levels() - 用
as_index=False可避免生成 MultiIndex,但会把键转为普通列——适合立刻导出,不适合链式聚合
最常被忽略的是分组键的 dtype:整数型键和字符串型键哪怕值一样(如 1 和 '1'),也会被当成完全不同的组。别依赖 str 强转隐式对齐,显式统一再分组。










