按自定义字典映射替换DataFrame内NaN值时无法覆盖全部缺失值
NaN定向替换遗漏的修复方案
问题根因
- 基础写法层面:pandas 的
replace()方法默认是非原地操作,会返回处理后的新DataFrame对象,不会直接修改原对象。如果执行代码时没有把replace()的返回值重新赋值给df_sample,原表不会发生任何变更。结合你给出的输出样例,绝大多数列的NaN已经被成功替换,说明你大概率已经完成了返回值赋值,剩余的替换遗漏来自第二类场景。 - 特殊列类型的静默失效:从输出样例中
px_prev列存在值为(0.0712, 0.508]的分箱结果可以判断,该列是通过pd.cut()生成的Categorical分类列。这类列存在固定的合法值集合(categories),如果预设的填充值(你给该列配置的填充值是-1)不在这个合法值集合内,直接执行replace(np.nan, 对应值)操作会被静默跳过,不会抛出报错也不会完成填充——因为Categorical类型不允许写入不在类别列表内的值,不会自动扩展合法值范围。
你当前的场景完全匹配这个特征:px_prev列现有值全部是分箱区间字符串,没有数值-1对应的合法类别,所以对应位置的NaN没有被替换,其余普通类型列的替换都能正常生效。
修复步骤
- 第一步:修正基础写法,确保替换操作的结果被正确保存,避免非原地操作的无效执行:
import numpy as np values = {'pitch_type': 'UN', 'px': -1, 'pz': -1, 'pitch_type_prev': -1,'px_prev': -1, 'pz_prev': -1} # 必须接收replace的返回值 df_sample = df_sample.replace(np.nan, values) - 第二步:针对
px_prev这类Categorical分类列做适配处理,在执行填充前先把预设的填充值加入该列的合法类别集合,否则填充操作会静默失效:# 给Categorical列添加缺失值填充用的合法类别 df_sample['px_prev'] = df_sample['px_prev'].cat.add_categories(-1) - 更高效的替代方案:可以直接用
fillna()完成逐列定向填充,比逐值匹配的replace()执行速度更快,同样需要先给Categorical列添加合法填充类别:# 先给分类列加填充用的合法类别 df_sample['px_prev'] = df_sample['px_prev'].cat.add_categories(-1) # 逐列按照预设规则填充NaN df_sample = df_sample.fillna(values) - 可选处理方式:如果不需要保留
px_prev列的Categorical类型,也可以先把该列转成普通object类型再执行填充,跳过类别添加的步骤:df_sample['px_prev'] = df_sample['px_prev'].astype(object) df_sample = df_sample.fillna(values)
内容的提问来源于stack exchange,提问作者Iris
相关产品推荐
相关产品推荐

