Pandas中map函数填充NaN时整列数据被清空的问题排查
Pandas填充NaN值时整列变空的问题分析
问题背景
我有一个包含多列的Pandas DataFrame,其中Code列为object类型,存在NaN缺失值,其余数据为数字或字母。希望仅对NaN值使用map/set_index函数填充,编写了如下代码:
for row in df['Code']: if pd.isnull(row) == True: df['Code']= df['account'].map(df_2.set_index('AccountID')['AccountCode']) else: None
执行后Code整列数据被清空,全变为NaN。
原始Code列数据:
0 23050178040 1 23050178040 2 23050178040 3 23050178106 4 23050178040 ... 288 23050942326 289 23050942326 290 NaN 291 23050942858 292 NaN Name: Code BU, Length: 293, dtype: object
执行后的结果:
0 NaN 1 NaN 2 NaN 3 NaN 4 NaN ... 288 NaN 289 NaN 290 NaN 291 NaN 292 NaN Name: Code BU, Length: 293, dtype: object
问题原因
- 循环逻辑错误:遍历
df['Code']的每一行时,只要遇到第一个NaN,就会直接把整个Code列替换成df['account'].map(...)的结果。如果这个map的结果本身大部分是NaN(比如df['account']和df_2的AccountID匹配不上),就会覆盖掉所有原有非NaN的值。后续遇到非NaN行时,代码不会恢复原来的值,最终整列都变成NaN。 - 违背Pandas矢量化特性:逐行循环操作Pandas数据框效率极低,且容易出现这种全列覆盖的逻辑失误。你原本的意图是仅填充NaN,但代码逻辑变成了“只要存在NaN行,就替换整列”。
- 匹配失败可能性:如果
df['account']中的值和df_2的AccountID完全不匹配,map操作会返回全NaN的Series,替换后整列自然全是空值。
正确解决方案
用Pandas的矢量化操作实现仅填充NaN值,保留原有数据:
方法1:使用fillna
# 先构建映射关系 code_mapping = df_2.set_index('AccountID')['AccountCode'] # 仅填充Code列的NaN值 df['Code'] = df['Code'].fillna(df['account'].map(code_mapping))
方法2:使用loc定位NaN行
code_mapping = df_2.set_index('AccountID')['AccountCode'] # 精准定位Code列的NaN行,用对应account匹配填充 df.loc[df['Code'].isna(), 'Code'] = df.loc[df['Code'].isna(), 'account'].map(code_mapping)
内容的提问来源于stack exchange,提问作者Heltal
相关产品推荐
相关产品推荐

