如何使用Pandas/Numpy实现更优雅的分组缺失值填充与值替换?
按type分组填充缺失value的高效实现
原有代码的问题
当前逐行遍历的实现存在两个明显缺陷:
- 运行效率极低:逐行遍历过程中每次都要全表扫描匹配对应type的行、计算众数,时间复杂度为O(n²),数据量稍大就会运行缓慢
- 易出现修改失效:
iterrows返回的是行对象的副本,直接给row['value']赋值无法修改原DataFrame,实际运行时会触发SettingWithCopyWarning,最终填充结果不会生效
基于Pandas内置方法的实现
全程不需要写自定义循环函数,仅通过向量化操作即可完成,效率比逐行遍历高1~2个数量级,完全匹配你想用fillna这类内置函数的需求:
- 从现有非缺失值的行中,自动提取
type对应固定value的映射关系(不需要手动硬编码A→D这类规则,完全从现有数据中学习映射) - 补充
type为NaN时对应的映射值N - 调用内置的
fillna方法,仅对原value列的缺失位置完成填充
可直接运行的代码
import pandas as pd import numpy as np df = pd.DataFrame({"type": ["A", "B", "C", "A", "B", "C", "A", "B", "C", np.NaN, np.NaN, np.NaN], "value": ["D", "E", "F", "D", "E", "F", np.NaN, np.NaN, np.NaN, np.NaN, "N", "N"] }) # 提取现有非缺失行的 type -> value 映射 value_map = ( df.dropna(subset=["value"]) # 过滤掉value缺失的行,避免干扰映射提取 .drop_duplicates(subset=["type"]) # 同type仅保留一条映射关系 .set_index("type")["value"] .to_dict() ) # 补充type为NaN时的映射规则 value_map[np.nan] = "N" # 用内置fillna完成缺失值填充,非缺失的原value会完全保留 df["value"] = df["value"].fillna(df["type"].map(value_map)) print(df)
运行上述代码的填充结果和预期完全一致:
- 原value缺失的A/B/C行分别填充为D/E/F
- 原value缺失的type为NaN的行填充为N
- 原本就有有效value的行不会被修改
适配特殊场景
如果后续数据中同type出现多个不同的非缺失value,只需要调整映射提取的逻辑,整体填充流程不需要改动——直接用groupby取众数作为每个type对应的填充值即可:
# 同type下存在多个value时,自动取出现次数最多的值作为填充依据 value_map = df.groupby("type")["value"].agg(pd.Series.mode).to_dict()
内容的提问来源于stack exchange,提问作者h1smajesty
相关产品推荐
相关产品推荐

