pandas如何实现左表列匹配右表任意两列的DataFrame合并
实现方案
下面提供3种适配不同场景的实现方式:
方案1:两次左合并后合并结果(最简洁,仅适用于2个匹配列场景)
先分别按右表的两个列做左连接,再用combine_first合并两个结果的非空值,自动补全缺失的匹配行:
import pandas as pd import numpy as np # 测试数据 df_1 = pd.DataFrame({'col' : ['a', 'b', 'c']}) df_2 = pd.DataFrame({'col_a' : ['a', 'b', np.nan], 'col_b' : ['z', np.nan, 'c']}) # 分别按两个列做左合并 merge_a = df_1.merge(df_2, how='left', left_on='col', right_on='col_a') merge_b = df_1.merge(df_2, how='left', left_on='col', right_on='col_b') # 合并结果,优先保留col_a的匹配结果,缺失值用col_b的匹配结果填充 res = merge_a.set_index('col').combine_first(merge_b.set_index('col')).reset_index()
运行后输出结果和期望完全一致:
col col_a col_b 0 a a z 1 b b NaN 2 c NaN c
方案2:长表转换后匹配(通用方案,支持N个匹配列)
如果后续需要匹配的右表列不止2个,推荐用melt转成长表后匹配,匹配完成后再转回宽表,扩展性更强:
# 将df_2的匹配列转为长表,过滤空值 df2_melt = df_2.melt( value_vars=['col_a', 'col_b'], value_name='match_key', ignore_index=False ).dropna(subset=['match_key']) # 左连接匹配 res = df_1.merge(df2_melt, how='left', left_on='col', right_on='match_key') # 转回宽表还原原始列结构 res = res.pivot(index='col', columns='variable', values='value').reset_index().rename_axis(columns=None)
方案3:自定义匹配逻辑(灵活调整优先级)
如果需要自定义匹配规则、匹配优先级,或者需要加额外匹配条件的场景,可以用apply逐行匹配:
def match_row(x): # 优先匹配col_a match = df_2[df_2['col_a'] == x] if not match.empty: return match.iloc[0] # 未匹配到再匹配col_b match = df_2[df_2['col_b'] == x] if not match.empty: return match.iloc[0] # 都没匹配到返回空值 return pd.Series([np.nan, np.nan], index=['col_a', 'col_b']) res = df_1.join(df_1['col'].apply(match_row))
内容的提问来源于stack exchange,提问作者NBK
相关产品推荐
相关产品推荐

