使用Pandas判断列值是否存在于另一数据框多列并新增匹配列报错求助
解决Pandas跨表匹配并新增标记列的问题
先聊聊你代码里的两个错误根源:
- 第一个
IndexError:你用df_comparing.columns[0,1]取前两列的写法不对,Pandas的列索引对象不支持元组索引,要取多列得用双层方括号[[0,1]],更稳妥的是用iloc[:, [0,1]]按位置直接取前两列。另外就算取对了两列,直接对DataFrame用isin会返回布尔值的DataFrame,没法直接转成整数列。 - 第二个
AttributeError:纯粹是拼写失误,astpye应该写成astype,不过就算改对了,只取单列的话也只能判断单列是否匹配,没法实现你要的「第0列或第1列任一匹配」的需求。
另外你的样本数据有个小问题:df_comparing里Line no只有3个元素,但Line addition有6个,创建DataFrame时会报错,我先帮你修正了样本数据,再给你两种可行的实现方案:
方法一:用apply逐行判断(直观易懂)
这种方式逻辑清晰,适合新手理解:
import pandas as pd import numpy as np # 修正后的样本数据(保证每行对应) df_comparing = pd.DataFrame({ 'Line no': ['AL5176', 'AL5737', 'AL5978', 'AL1234', 'AL2345', 'AL3456'], 'Line addition': [np.nan, np.nan, np.nan, 'AL9876', 'AL6789', 'AL5945'] }) df_compare_basis = pd.DataFrame({ 'DataLineID:': ['AL5176', 'AL5737', 'AL5978','AL9876', 'AL6789', 'AL5945'] }) # 把目标ID转成集合,提升查询效率 target_ids = set(df_compare_basis['DataLineID:']) # 新增Match列:只要第0列或第1列的值在目标集合里,就标记1,否则0 df_comparing['Match'] = df_comparing.apply( lambda row: 1 if (row.iloc[0] in target_ids) or (pd.notna(row.iloc[1]) and row.iloc[1] in target_ids) else 0, axis=1 ) print(df_comparing)
这里加了pd.notna(row.iloc[1])是为了处理NaN值,避免把NaN误判为匹配(毕竟NaN不在目标集合里)。
方法二:用stack+isin+unstack(更高效的向量操作)
如果你的数据量很大,用向量操作比apply快很多:
# 同样先准备目标集合 target_ids = set(df_compare_basis['DataLineID:']) # 把前两列堆叠成Series,判断每个值是否匹配,再按行取最大值(只要有一个匹配就是1) df_comparing['Match'] = ( df_comparing.iloc[:, [0,1]] .stack() .isin(target_ids) .unstack() .max(axis=1) .astype(int) )
这个方法利用Pandas的向量化操作,避免了逐行循环,处理大数据集时性能优势明显。
运行后你就能得到期望的结果:前3行因为Line no匹配标记1,后3行因为Line addition匹配标记1。
内容的提问来源于stack exchange,提问作者cd-6
相关产品推荐
相关产品推荐

