别再只会用0填充了!Pandas df.fillna()的5个高阶用法,让你的数据清洗更专业

张开发
2026/4/19 18:26:39 15 分钟阅读

分享文章

别再只会用0填充了!Pandas df.fillna()的5个高阶用法,让你的数据清洗更专业
别再只会用0填充了Pandas df.fillna()的5个高阶用法让你的数据清洗更专业每次看到数据集里的NaN值就条件反射地填0是时候升级你的数据清洗武器库了。在真实业务场景中简单粗暴的零值填充可能掩盖数据分布特征甚至导致分析结论偏差。本文将带你突破基础用法掌握五种基于业务逻辑的智能填充策略。1. 为什么零值填充可能是个糟糕的选择刚接触数据分析时我们总喜欢用df.fillna(0)快速解决缺失值问题。但真实业务数据中零值填充可能引发三个典型问题扭曲数据分布当缺失值集中在特定区间时零值填充会人为制造异常低值点。比如电商用户消费金额字段零值会拉低平均消费水平。误导聚合计算统计指标如总和、平均值会因零值填充而产生偏差。某零售连锁店曾因将缺货日销量填零导致季度营收虚降12%。掩盖业务问题某些场景下缺失值本身就是重要业务信号。信用卡申请表中的收入缺失可能暗示用户属于特定群体。# 错误填充示例销售数据零值填充 sales_data pd.DataFrame({ date: pd.date_range(2023-01-01, periods5), revenue: [1200, 1500, np.nan, 1800, np.nan] }) # 错误做法直接填零 naive_fill sales_data.fillna(0) print(失真的平均营收:, naive_fill[revenue].mean()) # 更合理的做法使用前值填充 smart_fill sales_data.ffill() print(修正后的平均营收:, smart_fill[revenue].mean())提示在金融、医疗等对数据准确性要求高的领域错误的填充方法可能导致决策失误甚至合规风险。2. 基于数据分布的统计量填充策略当数据存在自然波动区间时统计量填充比固定值更合理。但不同场景需要选择不同的统计量统计量适用场景优势注意事项均值数据分布对称且无极端值保持数据集中趋势对异常值敏感中位数存在离群值的偏态分布抗干扰性强可能低估真实波动众数分类数据或离散型数值保持数据模态特征不适用于连续型数值截尾均值有温和离群值兼顾鲁棒性和效率需要人工设定截尾比例# 多统计量填充实战 product_ratings pd.DataFrame({ product_id: [101, 102, 103, 104, 105], rating: [4.5, np.nan, 3.8, np.nan, 4.2] }) # 动态选择填充策略 if product_ratings[rating].skew() 1: # 严重偏态 fill_value product_ratings[rating].median() else: fill_value product_ratings[rating].mean() ratings_filled product_ratings.fillna(fill_value)对于时间序列数据还可以使用滚动窗口统计量# 滚动窗口均值填充 stock_prices pd.Series([45.6, 46.2, np.nan, np.nan, 47.8, 48.3]) window_mean stock_prices.rolling(3, min_periods1).mean() filled_prices stock_prices.fillna(window_mean)3. 前后向填充的进阶应用场景methodffill和methodbfill看似简单但在特定场景下有惊人效果设备传感器数据当采集短暂中断时前值填充最能保持物理连续性用户行为序列网页浏览记录中的缺失用后值填充可能更符合实际路径财务报表数据会计科目余额适合前值填充体现账户连续性# 多维度前值填充 factory_sensors pd.DataFrame({ timestamp: pd.date_range(2023-06-01 08:00, periods10, freqH), temp: [28.5, 28.7, np.nan, np.nan, 29.1, 29.0, np.nan, 28.9, 28.8, 28.7], pressure: [101.3, 101.2, 101.4, np.nan, np.nan, 101.1, 101.0, 100.9, np.nan, 100.8] }) # 按设备分组后前值填充 filled_sensors (factory_sensors .groupby(equipment_id) .apply(lambda x: x.ffill().bfill()))注意前后向填充可能导致数据滞留效应在长期缺失段落后会重复相同值此时应设置limit参数限制最大填充步长。4. 基于业务规则的差异化填充高阶数据分析师需要将业务知识编码到填充逻辑中案例电商用户画像填充会员等级白银会员缺失用普通填充钻石会员缺失用黄金填充最近购买日超过1年未购用户填流失新用户填新客客单价不同品类采用不同中位数填充# 业务规则填充函数 def business_aware_fill(df): # 会员等级规则 df[member_level] np.where( (df[member_level].isna()) (df[member_days]365), 普通, df[member_level] ) # 购买行为规则 df[last_purchase] np.where( df[last_purchase].isna(), pd.to_datetime(2023-01-01) - pd.to_timedelta(df[user_days], unitD), df[last_purchase] ) # 品类差异化填充 category_medians df.groupby(category)[price].median() df[price] df.apply( lambda row: category_medians[row[category]] if pd.isna(row[price]) else row[price], axis1 ) return df5. 预测模型填充机器学习的降维打击当缺失机制复杂时如MNAR可训练简单预测模型from sklearn.experimental import enable_iterative_imputer from sklearn.impute import IterativeImputer # 创建模拟数据 data pd.DataFrame({ age: [25, 30, np.nan, 40, 45], income: [50000, np.nan, 70000, np.nan, 90000], spending: [2000, 3000, 4000, np.nan, 5000] }) # 使用随机森林进行多重插补 imputer IterativeImputer(random_state42) imputed_data pd.DataFrame(imputer.fit_transform(data), columnsdata.columns)模型选择建议线性回归变量间关系近似线性时随机森林存在复杂非线性关系时KNN小数据集且变量维度低时6. 填充质量验证与效果评估填充后必须进行验证常用方法包括分布对比检验# KS检验填充前后分布 from scipy.stats import ks_2samp original df[feature].dropna() filled df[feature].fillna(...) ks_stat, p_value ks_2samp(original, filled)变量关系保持度# 计算填充前后相关系数变化 original_corr df.corr() filled_corr filled_df.corr() corr_diff (original_corr - filled_corr).abs().mean().mean()业务合理性检查数值型检查是否超出合理范围分类变量检查类别比例是否突变时间序列检查填充后是否出现异常波动实际项目中我会先抽取5%的完整数据作为验证集人工评估不同填充方法的效果。记住没有绝对最优的填充方法只有最适合当前业务场景的选择。

更多文章