基于ID多条件匹配合并Pandas DataFrame并添加指定列
解决方案
要实现将df2指定列匹配到df1的需求,核心是处理双ID匹配(IDL1/IDL2)以及航线组合排除逻辑,以下是通用实现方案:
实现思路
- 先把df2拆分为基于IDL1和IDL2的两个子表,统一ID列名后合并,过滤掉无效的-1记录,得到所有可能的ID关联关系
- 将df1与处理后的df2关联,再通过航线组合对比过滤掉不符合条件的记录
- 对每个ID保留唯一有效匹配(按预期输出取第一条匹配结果)
完整代码
import pandas as pd # 初始化原始数据 data1 = {'ID': [385908, 385909, 757947, 757946], 'A': ['LH', 'LH', 'LH', 'LH'], 'F': [646, 646, 646, 646], 'Orig': ['FRA', 'FRA', 'NQZ', 'NQZ'], 'Dest': ['NQZ', 'NQZ', 'ALA', 'ALA'], 'DayU': [1, 6, 1, 6], 'DepU': [650, 650, 1130, 1130]} data2 = {'A': ['LH', 'LH', 'LH', 'LH', 'LH', 'LH'], 'F': [646, 646, 646, 646, 646, 646], 'Orig2': ['FRA', 'FRA', 'FRA', 'FRA', 'NQZ', 'NQZ'], 'Dest2': ['ALA', 'ALA', 'NQZ', 'NQZ', 'ALA', 'ALA'], 'DayL': [1, 6, 1, 6, 2, 7], 'DepL': [710, 710, 710, 710, 50, 50], 'IDL1': [385908, 385909, 385908, 385909, 757947, 757946], 'IDL2': [757947, 757946, -1, -1, -1, -1]} df1 = pd.DataFrame(data1) df2 = pd.DataFrame(data2) # 1. 拆分df2为IDL1和IDL2两个维度的匹配表,统一ID列名 df2_idl1 = df2[['IDL1', 'Orig2', 'Dest2', 'DayL']].rename(columns={'IDL1': 'ID'}) df2_idl2 = df2[['IDL2', 'Orig2', 'Dest2', 'DayL']].rename(columns={'IDL2': 'ID'}) # 合并并过滤无效ID df2_matches = pd.concat([df2_idl1, df2_idl2]).query('ID != -1').reset_index(drop=True) # 2. 关联df1与匹配表,过滤航线组合相同的记录 merged_df = pd.merge(df1, df2_matches, on='ID', how='left') filtered_df = merged_df[~((merged_df['Orig'] == merged_df['Orig2']) & (merged_df['Dest'] == merged_df['Dest2']))] # 3. 确保每个ID仅保留一条有效匹配结果 final_result = filtered_df.groupby('ID').first().reset_index() # 输出验证 print(final_result)
代码说明
- 拆分合并df2:将df2的IDL1和IDL2分别作为匹配ID,统一列名后合并,排除-1这类无效ID,避免干扰匹配
- 关联过滤:通过
merge实现两表关联,用布尔索引精准过滤掉航线组合完全相同的记录 - 去重处理:使用
groupby('ID').first()保证每个ID只保留一条有效匹配,与预期输出对齐
输出结果
运行代码后将得到与需求完全一致的结果:
ID A F Orig Dest DayU DepU Orig2 Dest2 DayL 0 385908 LH 646 FRA NQZ 1 650 FRA ALA 1 1 385909 LH 646 FRA NQZ 6 650 FRA ALA 6 2 757947 LH 646 NQZ ALA 1 1130 FRA ALA 1 3 757946 LH 646 NQZ ALA 6 1130 FRA ALA 6
内容的提问来源于stack exchange,提问作者the phoenix
相关产品推荐
相关产品推荐

