会出错,因GroupBy对象无fillna方法;须用transform/apply等方法实现组内填充,且需注意全NaN组返回NaN、多列需分步处理等细节。

groupby后直接用fillna会出错吗
会,而且很隐蔽。默认情况下 fillna() 作用于整个 DataFrame 或 Series,不感知分组结构。如果你写了 df.groupby('category').fillna(0),Pandas 会报 AttributeError: 'DataFrameGroupBy' object has no attribute 'fillna'——因为 GroupBy 对象本身没有 fillna 方法。
必须先调用 apply()、transform() 或对分组后的具体列做操作,否则语法就过不去。
常见错误现象:
- 误写
df.groupby('col').fillna(...)→ 直接报错 - 用
apply(lambda x: x.fillna(...))却忘了返回值类型,导致结果变成 Series 套 Series - 对多列分组后想按组填充均值,却只写了单列名,触发
KeyError
用transform做组内均值/众数填充最稳妥
transform() 能保持原始索引对齐,且天然适配分组上下文,是填充缺失值最常用也最安全的方式。
使用场景:
- 数值列用组内均值填空(如每个城市销售额的平均值补缺失)
- 分类列用组内众数填空(如每个部门最常见的职级补缺失)
- 需要保留原始行数和顺序,不能丢数据
实操建议:
- 数值型:用
df.groupby('region')['sales'].transform('mean')→ 自动广播到每行,再赋值给原列 - 分类型:先定义函数
lambda x: x.mode()[0] if not x.mode().empty else np.nan,再传给transform() - 避免直接写
transform(np.mean),它对含 NaN 的组会返回 NaN;而字符串'mean'会被 Pandas 内部忽略 NaN 计算
fill_value参数在agg里没用,别乱套
agg() 是聚合操作,目的是降维(行数变少),不是填充。你在 df.groupby('A').agg({'B': 'mean'}) 里加 fill_value=0 不生效——agg 根本不接受这个参数。
容易踩的坑:
- 混淆
transform和agg:前者输出同长,后者输出更短 - 试图用
fillna()配合agg结果反向映射回原表,逻辑绕但易出错(比如索引对不上、类别缺失) - 用
apply()+fillna()时没设inplace=False,或忘了返回整个子 DataFrame
多列分组+多策略填充要拆开写
没有“一行代码搞定所有列不同策略”的简洁写法。Pandas 不支持在单个 transform 中为不同列指定不同填充逻辑。
实操建议:
- 逐列处理:先处理
df['age'] = df.groupby(['city', 'gender'])['age'].transform('median'),再处理df['status'] = df.groupby(['city', 'gender'])['status'].transform(lambda x: x.mode()[0] if len(x.mode()) else None) - 避免链式赋值警告:用
.loc显式定位,比如df.loc[df['age'].isna(), 'age'] = df.groupby(['city', 'gender'])['age'].transform('median') - 性能注意:多次
groupby会重复计算分组键哈希,大数据量时可先缓存g = df.groupby(['city', 'gender']),再反复用g['age'].transform(...)
组内填充真正麻烦的不是语法,而是缺失机制本身——比如某组全为 NaN,transform('mean') 就返回全 NaN,不会 fallback 到全局均值。这点很容易被忽略,直到上线后发现某些组的空值根本没填上。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











