fillna不支持“前后向”组合填充,因其method参数仅接受单一方法(如'ffill'或'bfill'),需分步调用实现优先级控制;实际常用先ffill再bfill或反之,并配合limit限制填充距离,数值列宜插值、分类列宜众数,且需注意mode空值及插值边界问题。

fillna 为什么不能直接填“前后向”?
fillna 本身不支持“先向前填、再向后填”这种组合逻辑。它只接受标量、字典、Series 或方法名(如 'ffill'、'bfill'),但这些方法是互斥的——传 method='ffill' 就只前向,传 method='bfill' 就只后向,没法自动选更合理的那个。
用 ffill 和 bfill 分两步填充更可控
实际中更常用的是先 ffill 再 bfill(或反过来),靠顺序控制优先级。比如想优先用前面的有效值,再用后面的兜底:
-
df.fillna(method='ffill').fillna(method='bfill'):先向前填,空缺再向后填 -
df.fillna(method='bfill').fillna(method='ffill'):先向后填,再向前填 - 对单列操作更安全:
df['col'] = df['col'].fillna(method='ffill').fillna(method='bfill')
注意:连续多个 NaN 时,ffill 只能填到第一个非空值之后的位置,后续仍空;这时第二步 bfill 才起作用。
限制填充范围避免“跨太远”
默认 ffill/bfill 会一直填到头或尾,可能把一个值复制几十行,违背业务直觉。用 limit 参数可约束步数:
-
df.fillna(method='ffill', limit=1):每个NaN最多用前 1 个值填充 -
df.fillna(method='bfill', limit=2):最多向后取 2 行内的值 -
limit对时间序列特别有用,比如只允许用“最近 7 天”的数据补缺失
注意:limit 是按行/列方向计数,不是按时间戳跨度;若需按时间间隔限距,得先用 asfreq 或重采样对齐。
混合策略:数值列用插值,分类列用众数
没有万能填充法。数值型字段(如温度、价格)适合线性插值:df['temp'].interpolate(method='linear');分类字段(如城市、状态)更适合用众数:df['city'].fillna(df['city'].mode()[0])。
容易踩的坑:
-
mode()可能返回空 Series(全 NaN 或无重复值),要加if not df['col'].mode().empty判断 -
interpolate默认跳过 NaN,但遇到开头/结尾连续 NaN 仍无法插值,得配合limit_area='inside'控制范围 - 混用策略时别直接链式调用
fillna,建议按列分别处理再合并
真正麻烦的不是怎么填,而是填完要不要加标记列(如 is_imputed)来记录哪些值被干预过——这在模型训练和审计时很关键,但常被忽略。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











