You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于OR条件对两个Pandas DataFrame执行左连接?

问题:多列OR条件的Left Join实现

数据准备

ABC DataFrame

import pandas as pd

ABC_data = [['A001', 'B001','C001','xxx','nnn'], ['A002', 'B002','C002','yyy','mmm'], ['A003', 'B003','C003','zzz','ooo']] 
ABC = pd.DataFrame(ABC_data, columns = ['A', 'B','C','Other_1','Other_2']) 
print(ABC)

输出:

A     B     C Other_1 Other_2
0  A001  B001  C001     xxx     nnn
1  A002  B002  C002     yyy     mmm
2  A003  B003  C003     zzz     ooo

LOP DataFrame

LOP_data = [['A002','sth1'], ['B004','sth2'], ['C002','sth3'], ['C003','sth4']] 
LOP = pd.DataFrame(LOP_data, columns = ['L', 'other_info']) 
print(LOP)

输出:

L other_info
0  A002       sth1
1  B004       sth2
2  C002       sth3
3  C003       sth4

需求说明

以ABC为左表、LOP为右表执行left join,连接条件为:LOP['L'] 等于 ABC['A'] 或 ABC['B'] 或 ABC['C']。

注意:L的值只会匹配A/B/C中的某一列,不会同时匹配多列。匹配成功则合并LOP的所有列;无匹配项则对应列值为null。

期望结果

A     B     C Other_1 Other_2     L L_other_info
0  A001  B001  C001     xxx     nnn  None         None
1  A002  B002  C002     yyy     mmm  A002         sth1
2  A002  B002  C002     yyy     mmm  C002         sth3
3  A003  B003  C003     zzz     ooo  C003         sth4

已尝试方案

  • 尝试用merge函数,但仅支持AND条件,无法满足OR需求;
  • 复制ABC三份,分别置空不同关键列后与LOP单独合并再拼接,但无法正确去重并保留无匹配的null行,最终失败。

解决方案

核心思路是将ABC的多列匹配条件转化为长格式的一对一匹配,再合并还原,具体实现如下:

# 为ABC添加索引,方便后续还原原结构
ABC = ABC.reset_index()

# 将A/B/C列转为长格式,保留其他非匹配列
melted_ABC = ABC.melt(
    id_vars=['index', 'Other_1', 'Other_2'],
    value_vars=['A', 'B', 'C'],
    value_name='L'
)

# 和LOP执行left join
merged = melted_ABC.merge(LOP, on='L', how='left')

# 合并回原表的基础列,调整列名
result = merged.merge(ABC, on='index', how='left')
result = result[['A', 'B', 'C', 'Other_1_x', 'Other_2_x', 'L', 'other_info']]
result.columns = ['A', 'B', 'C', 'Other_1', 'Other_2', 'L', 'L_other_info']

# 处理无匹配的行:仅保留一行空值记录
mask = result[['L', 'L_other_info']].isna().all(axis=1)
non_null_rows = result[~mask]
null_rows = result[mask].drop_duplicates(subset=['A', 'B', 'C'])

# 合并结果并按原索引排序
final_result = pd.concat([null_rows, non_null_rows]).sort_index()
print(final_result)

执行后即可得到符合期望的结果。


内容的提问来源于stack exchange,提问作者xlxdxf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 20:57:35