如何用Pandas对比DataFrame行内列值并生成指定新列?
解决Pandas DataFrame按规则生成新列的问题
示例数据
首先定义示例DataFrame:
import pandas as pd import numpy as np df1 = pd.DataFrame([["A", "B"], ["C", "D"], [np.nan, "A"], ["B", np.nan], [np.nan, np.nan], ["E", "E"]], columns=["col1", "col2"])
核心规则回顾
生成新列col3的规则:
- 两列值不同且均非NaN → 选择指定列(示例中为
col1) - 其中一列是NaN → 选择非NaN值
- 两列值相等 → 任选其一(示例中选
col1) - 两列均为NaN → 保留NaN
方法一:简洁版(利用where处理空值)
如果指定列为col1,直接用where优先取col1,空值时取col2,刚好覆盖所有规则:
df1['col3'] = df1['col1'].where(df1['col1'].notna(), df1['col2'])
验证结果:col3的值为['A', 'C', 'A', 'B', np.nan, 'E'],完全符合期望。
方法二:修正np.select逻辑
针对你之前用np.select踩的NaN判断坑,改用isna()/notna()明确空值条件,按优先级排列规则:
conditions = [ # 两列均非空且值不同 → 选col1 (df1['col1'].notna() & df1['col2'].notna() & (df1['col1'] != df1['col2'])), # col1非空、col2为空 → 选col1 (df1['col1'].notna() & df1['col2'].isna()), # col1为空、col2非空 → 选col2 (df1['col1'].isna() & df1['col2'].notna()), # 两列值相等(含均非空相等)→ 选col1 (df1['col1'] == df1['col2']) ] choices = [ df1['col1'], df1['col1'], df1['col2'], df1['col1'] ] df1['col3'] = np.select(conditions, choices, default=np.nan)
这个方法把所有规则拆解为明确条件,适合需要调整规则优先级或指定列的场景。
方法三:combine_first+条件判断
先用combine_first处理空值和相等的情况,再单独覆盖“两列不同选指定列”的规则:
# 先处理空值和相等情况:优先取col1,空值时取col2 temp_col = df1['col1'].combine_first(df1['col2']) # 筛选两列均非空且值不同的行,强制替换为col1 mask = df1['col1'].notna() & df1['col2'].notna() & (df1['col1'] != df1['col2']) df1['col3'] = np.where(mask, df1['col1'], temp_col)
关键注意点
- 永远不要直接用
==或!=判断NaN,因为np.nan == np.nan返回False,会导致逻辑错误,必须用isna()(判断为空)或notna()(判断非空)。
内容的提问来源于stack exchange,提问作者antusystem
相关产品推荐
相关产品推荐

