如何对含缺失值的不同数据列采用差异化填充策略?
多列差异化缺失值填充实现方案
核心逻辑是按列单独匹配填充规则,不要对整个DataFrame做统一填充,既可以用pandas原生方法快速实现,也可以结合sklearn的预处理工具搭建标准化流水线,两种方案都不会出现逻辑冲突。
方案1:逐列原生实现(适合快速数据处理场景)
先导入依赖,构造测试数据集:
import pandas as pd import numpy as np from sklearn.impute import SimpleImputer # 示例数据集,3列均包含缺失值 df = pd.DataFrame({ 'col1': [1, np.nan, 3, np.nan, 5], # 第一列:缺失值填0 'col2': [2, 4, np.nan, 8, np.nan], # 第二列:均值/中位数填充 'col3': [np.nan, 3, 6, np.nan, 9] # 第三列:SimpleImputer填充指定常量 })
按列分别执行填充逻辑:
- 第一列直接调用
fillna()填充0,适合缺失值本身代表“无/计数为0”语义的字段(比如未产生行为的用户计数、未消费金额等场景)
df['col1'] = df['col1'].fillna(0)
- 第二列根据字段分布选择统计值填充:近似正态分布选均值,偏态分布(存在极端值)选中位数,直接用pandas原生统计方法计算填充值即可,无需额外工具
# 均值填充示例,替换为median()即可切换为中位数填充 fill_val_col2 = df['col2'].mean() df['col2'] = df['col2'].fillna(fill_val_col2)
- 第三列用
SimpleImputer做常量填充,注意传入列时要用双中括号保留二维结构,符合转换器输入要求
# 初始化常量填充器,fill_value可根据业务需求指定,比如常用-999作为缺失标记 imputer_const = SimpleImputer(strategy='constant', fill_value=-999) df['col3'] = imputer_const.fit_transform(df[['col3']])
注意:如果是训练/测试集拆分场景,均值、中位数这类统计值必须只在训练集上计算,再用该值填充训练集和测试集,避免数据泄露。
方案2:ColumnTransformer流水线封装(适合工程化建模场景)
如果需要把预处理逻辑和后续建模流程打通,避免训练、推理阶段处理逻辑不一致,可以用ColumnTransformer把各列的填充规则绑定,一次性完成转换:
from sklearn.compose import ColumnTransformer # 为不同列绑定对应的填充处理器 fill_pipeline = ColumnTransformer( transformers=[ # 第一列常量填充0 ('col1_process', SimpleImputer(strategy='constant', fill_value=0), ['col1']), # 第二列均值填充,strategy改为'median'即可切换为中位数 ('col2_process', SimpleImputer(strategy='mean'), ['col2']), # 第三列填充指定常量-999 ('col3_process', SimpleImputer(strategy='constant', fill_value=-999), ['col3']) ], remainder='passthrough' # 未指定处理规则的列原样保留 ) # 拟合转换,输出为numpy数组,可直接转成DataFrame df_processed = pd.DataFrame( fill_pipeline.fit_transform(df), columns=df.columns )
两种方案选择参考:
- 做探索性分析、小数据集快速清洗:选逐列原生实现,代码直观调试成本低
- 搭建可复用的建模流水线、需要跨数据集复用填充规则:选ColumnTransformer封装方案,逻辑更规范,不容易出现训练测试偏差
内容的提问来源于stack exchange,提问作者Synonian_raj
相关产品推荐
相关产品推荐

