如何在Pandas中基于多列匹配合并两个DataFrame?
问题描述
现有两个DataFrame:
df1
A B C D 0 test1 test2 test3 test4 1 test22 test33 test23 test432 2 test54 test32 tes353 test98
初始df2
A B 0 test98 value1 1 test1 value2 2 test33 value3
需求:用df2的A列值匹配df1中的任意一列,将对应的df2的B列值添加到df1中,最终输出如下:
A B C D Value 0 test1 test2 test3 test4 value2 1 test22 test33 test23 test432 value3 2 test54 test32 tes353 test98 value1
补充需求
实际df2包含更多列:
A B C 0 test98 value1 value5 1 test1 value2 value6 2 test33 value3 value7
最终目标是将df1处理为:
A B C D Value Value2 0 test1 test2 test3 test4 value2 value6 1 test22 test33 test23 test432 value3 value7 2 test54 test32 tes353 test98 value1 value5
是否有方法实现该条件下的合并?
解决方案
可以用Pandas的melt、merge和pivot组合实现,步骤如下:
- 给df1添加行索引标识,用于后续合并后还原原结构:
import pandas as pd df1['row_id'] = df1.index
- 将df1转为长格式,把所有需匹配的列(A、B、C、D)整合到同一列,保留行索引:
df1_melted = df1.melt(id_vars='row_id', value_name='匹配值', var_name='原列')
- 重命名df2的列,对齐匹配字段并指定输出列名:
df2_renamed = df2.rename(columns={'A': '匹配值', 'B': 'Value', 'C': 'Value2'})
- 合并转换后的df1和重命名后的df2,通过
匹配值关联:
merged = pd.merge(df1_melted, df2_renamed, on='匹配值', how='left')
- 筛选出每行的有效匹配结果,合并回原df1结构:
result = pd.merge(df1, merged.dropna(subset=['Value'])[['row_id', 'Value', 'Value2']], on='row_id', how='left')
- 删除临时添加的
row_id列:
result = result.drop('row_id', axis=1)
运行上述代码后即可得到目标格式的DataFrame。
逻辑说明
melt将宽表转窄表,让df1所有列的匹配值集中到一列,解决“任意列匹配”的需求。row_id保留原行的唯一性标识,确保匹配结果能准确对应回df1的每一行。dropna筛选有效匹配行,因为每行只会有一个值能匹配df2,不会产生重复行。
内容的提问来源于stack exchange,提问作者user14073111
相关产品推荐
相关产品推荐

