如何用Pandas的isin或merge实现多列跨不同结构DataFrame匹配?
多列跨DataFrame匹配标记解决方案
方法1:使用merge(推荐,性能更优)
merge不需要两个DataFrame列数相同,只需指定匹配列的对应关系即可实现:
import pandas as pd # 初始化原始数据 d1={'A':[1,3,5,7,8,4,6],'B':[6,4,3,8,1,7,4], 'C':[2,5,8,9,8,4,7]} df1=pd.DataFrame(data=d1) d2={'a':[2,8,6,5,7],'b':[6,4,9,3,2]} df2=pd.DataFrame(data=d2) # 提取df1中用于匹配的A、B列,并重命名为df2的列名以匹配merge规则 df1_match_cols = df1[['A', 'B']].rename(columns={'A':'a', 'B':'b'}) # 左连接merge,保留df2所有行,标记匹配状态 df2_with_match = df2.merge( df1_match_cols.drop_duplicates(), # 去重避免匹配后行数膨胀 on=['a', 'b'], how='left', indicator='match_status' ) # 将匹配状态转为布尔值,True表示完全匹配 df2['is_matched'] = df2_with_match['match_status'] == 'both' print(df2)
运行输出:
a b is_matched 0 2 6 False 1 8 4 True 2 6 9 False 3 5 3 True 4 7 2 False
关键逻辑说明
- 先从df1中剥离出需要匹配的
A、B列,重命名为df2的a、b,确保merge时列名对应。 drop_duplicates()过滤df1中重复的(A,B)组合,避免merge后df2出现重复行。indicator参数新增的列会标记每行的匹配来源,'both'代表该行在两个DataFrame的匹配列中都存在,转为布尔值即为最终的匹配标记。
方法2:使用元组集合匹配(代码更简洁)
将df1的匹配列打包成元组集合,直接判断df2每行的(a,b)是否属于该集合:
import pandas as pd # 初始化原始数据 d1={'A':[1,3,5,7,8,4,6],'B':[6,4,3,8,1,7,4], 'C':[2,5,8,9,8,4,7]} df1=pd.DataFrame(data=d1) d2={'a':[2,8,6,5,7],'b':[6,4,9,3,2]} df2=pd.DataFrame(data=d2) # 生成df1中(A,B)的唯一元组集合 match_tuples = set(zip(df1['A'], df1['B'])) # 逐行判断是否匹配,生成标记列 df2['is_matched'] = df2.apply(lambda row: (row['a'], row['b']) in match_tuples, axis=1) print(df2)
运行输出与方法1完全一致。
关键逻辑说明
zip(df1['A'], df1['B'])将每行的A、B值打包为元组,转成集合后查询效率远高于列表。apply逐行遍历df2,判断当前行的(a,b)元组是否在匹配集合中,返回布尔值作为标记列。
内容的提问来源于stack exchange,提问作者HungryMolecule
相关产品推荐
相关产品推荐

