使用fillna需注意:ffill应加limit和axis约束;均值插补须先筛选数值列并避免全NaN列;混合插补要先ffill再均值;分组数据宜用groupby.transform而非全局均值;插补后须验证缺失率与业务合理性。

用 pandas.DataFrame.fillna 做前向填充时要注意方向和限制
前向填充(ffill)默认沿行方向向后传播上一个有效值,但容易忽略 limit 和 axis 参数的影响。比如对一列含多个连续缺失的序列直接 fillna(method='ffill'),可能把很早的值一路填到最后,掩盖数据断层。
实际建议按需加约束:
- 只填充最多连续 3 个缺失:用
fillna(method='ffill', limit=3) - 按行填充(而非默认列方向):指定
axis=1 - 若只想对某几列操作,避免全表误填:用
df[['col_a', 'col_b']].fillna(...)
均值插补必须区分数值列,且不能在原地修改原始数据
df.mean() 返回的是每列均值,但若 DataFrame 含非数值列(如字符串、时间戳),直接传给 fillna() 会报 TypeError: unsupported operand type(s) for +: 'float' and 'str'。更隐蔽的问题是:调用 df.fillna(df.mean()) 时,pandas 会自动按列对齐,但若某列全为 NaN,df.mean() 返回 NaN,导致该列仍无变化,不会报错也不会提示。
安全做法是显式筛选:
立即学习“Python免费学习笔记(深入)”;
- 先获取数值列:
num_cols = df.select_dtypes(include='number').columns - 计算并填充:
df[num_cols] = df[num_cols].fillna(df[num_cols].mean()) - 若需保留原始
df,务必赋值给新变量或使用copy=True
混合使用均值插补和前向填充要分步,顺序不能反
均值插补适合随机缺失,前向填充适合时序或有序数据中的短中断。两者混用时,如果先均值再 ffill,ffill 可能覆盖掉刚填的均值(尤其当均值填在开头,后面又有一串 NaN);反之,若先 ffill 再均值,ffill 后的列已无缺失,均值就不起作用。
典型合理流程是:
- 对时间敏感列(如
'timestamp','sensor_reading')单独做fillna(method='ffill', limit=5) - 对其他数值列统一用均值插补:
df[num_cols_no_ts] = df[num_cols_no_ts].fillna(df[num_cols_no_ts].mean()) - 避免对同一列反复
fillna,pandas 不会报错但逻辑易混乱
插补后务必检查是否引入偏差,特别是分组场景
用全局均值填充时,若数据存在明显分组结构(如不同用户、不同设备),全局均值会抹平组间差异。例如 df.groupby('device_id')['temp'].transform('mean') 得到的是每台设备的平均温度,比 df['temp'].mean() 更合理。
前向填充在非时序数据中也可能误导:比如按字母排序的客户名单里用 ffill,会让“张三”之后所有缺失行业都变成“互联网”,而实际可能是“制造业”居多。
最简验证方式:
- 插补前后对比缺失比例:
df.isna().sum() / len(df) - 抽样检查几行,确认填充值符合业务直觉
- 对关键指标(如均值、标准差)做前后快照,偏差超 5% 就得重新评估策略


















