fillna填均值需先显式计算,如df['col'].fillna(df['col'].mean());误传np.mean会填入函数对象;按列填充须用字典指定各列统计量,避免axis=1错误;inplace=true已弃用且易出错,应赋值回变量。

fillna 填均值前必须先算出来,不能直接传 np.mean
很多人写 df['col'].fillna(np.mean) 以为能自动计算,结果填进去的是函数对象本身,不是数值。Pandas 的 fillna 不会帮你调用函数,它只认具体值或支持的字符串(如 'ffill')。
正确做法是显式计算再传入:
-
df['col'].fillna(df['col'].mean())—— 注意:若列含NaN,mean()默认跳过,安全 -
df['col'].fillna(df['col'].median())—— 中位数对异常值更鲁棒 - 如果列是整型但均值是浮点,填充后列类型会变成
float64,后续可能影响存储或下游判断
按列分别填不同统计量,别用 axis=1 搞混方向
想对每列用各自的均值填充?常见错误是误设 axis=1,以为“横向填”,结果 Pandas 真的按行算均值(即每行所有非空值的平均),完全不是你要的。
正确方式是用字典传入各列对应值:
df.fillna({'A': df['A'].mean(), 'B': df['B'].median()})- 也可以用
apply预处理:df.apply(lambda s: s.fillna(s.mean() if s.dtype in ['float64', 'int64'] else s.mode()[0] if not s.mode().empty else None)),但注意mode()可能返回空 Series - 避免对字符列调
mean(),会报TypeError: Could not convert string to float
inplace=True 是陷阱,尤其在链式操作里
写 df.fillna(..., inplace=True) 看似省事,但一旦前面是视图(比如 df[df['x'] > 0]),就会触发 SettingWithCopyWarning,甚至静默失败——值没真填进去。
更稳的做法是始终赋值回变量:
df = df.fillna({'col1': df['col1'].mean(), 'col2': df['col2'].median()})- 如果数据很大,担心内存复制,可以确认是原 DataFrame 视图再谨慎用
inplace;但多数情况直接赋值更可预测 -
inplace=True在未来 Pandas 版本中已被标记为弃用,早适应无害
缺失值太多时,均值/中位数填充可能扭曲分布
当某列缺失率超过 30%,直接填均值会让方差缩水、长尾变平,模型训练时容易高估稳定性。这不是 fillna 的错,而是策略问题。
得先看缺失机制:
- 如果是随机缺失(MCAR),均值填充尚可接受
- 如果是与其它变量相关(MAR),比如收入缺失集中在“未填写职业”的人群,那该用分组均值:
df['income'].fillna(df.groupby('job')['income'].transform('mean')) - 缺失值本身可能是信号(如“未测血压”暗示健康风险),此时填均值反而抹掉关键信息,不如新增
income_missing布尔列
填之前先跑 df.isnull().sum() / len(df) 看比例,比急着敲 fillna 重要得多。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











