Pandas实现col3非空时替换col2值 解决iterrows赋值失效问题
原代码失效原因
你的代码有两个核心问题导致无法得到预期结果:
- 空值判断逻辑错误:
np.nan的特性是自身和自身不相等,执行np.nan != np.nan会返回True,因此你写的if row['col3'] != np.nan对所有行都会判定为成立,根本无法筛选出col3为空的行。判断空值要使用pandas/numpy提供的专用方法pd.notna()/pd.isna()。 - 赋值对象无效:
df.iterrows()返回的row是原数据行的副本,不是原DataFrame的视图引用,直接修改row的字段值不会同步改动原DataFrame的内容,相当于修改了一个用完就丢的临时变量,原数据不会有任何变化。
推荐实现方式
pandas中优先使用向量化操作实现需求,不要用逐行遍历,性能会比循环高几个数量级,代码也更简洁。
最贴合需求的写法:
# 逻辑:col3非空时取col3的值,否则保留原有col2的值 df['col2'] = df['col3'].where(df['col3'].notna(), df['col2'])
也可以用mask方法实现(和where判断逻辑相反),效果完全一致:
# 逻辑:col3非空时将col2替换为col3的值,否则保留原col2 df['col2'] = df['col2'].mask(df['col3'].notna(), df['col3'])
用你提供的示例数据运行上述代码,得到的结果完全匹配预期:
col1 col2 col3 0 1 2.0 NaN 1 4 5.0 NaN 2 6 8.0 8.0 3 1 9.0 9.0
不推荐的循环写法(仅做参考)
如果一定要用逐行遍历的逻辑,需要通过.loc定位原DataFrame的位置进行赋值,同时修正空值判断方法:
import pandas as pd for i, row in df.iterrows(): if pd.notna(row['col3']): df.loc[i, 'col2'] = row['col3']
这种写法在数据量较大时运行速度会远慢于向量化实现,非必要不要使用。
内容的提问来源于stack exchange,提问作者chitete
相关产品推荐
相关产品推荐

