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

如何基于多候选键列合并两个Pandas DataFrame

如何基于多候选键列合并两个DataFrame?

首先先复现你提供的示例数据:

import pandas as pd
import numpy as np

# 初始化df1
df1 = pd.DataFrame([[1,10,100],[2,20,np.nan],[3,30,300]], columns=["A","B","C"])
# 初始化df2
df2 = pd.DataFrame([[1,422],[10,72],[2,278],[300,198]], columns=["ID","Value"])

你的需求是:让df2的ID列匹配df1中A/B/C任意一列的值,只要匹配上就进行关联合并,最终保留所有匹配的结果(比如df1第一行同时匹配df2的ID=1和ID=10,所以输出两行)。

实现思路

核心思路是将df1的多候选键列转换为长格式,这样就能用单列和df2的ID做关联,之后再整理回目标格式:

  1. 给df1添加临时行标识,方便后续关联回原始行数据
  2. 使用pd.melt把df1的A/B/C列转成键值对形式,统一成ID列
  3. 过滤掉ID为NaN的行(避免无效匹配),然后和df2做内连接
  4. 清理临时列,整理成目标输出格式

完整代码实现

import pandas as pd
import numpy as np

# 初始化原始数据
df1 = pd.DataFrame([[1,10,100],[2,20,np.nan],[3,30,300]], columns=["A","B","C"])
df2 = pd.DataFrame([[1,422],[10,72],[2,278],[300,198]], columns=["ID","Value"])

# 步骤1:添加临时行ID,用于关联原始行数据
df1['row_id'] = df1.index

# 步骤2:将df1的A/B/C列转成长格式,生成统一的ID列
df1_melted = df1.melt(
    id_vars=['row_id', 'A', 'B', 'C'],  # 保留需要的原始列
    value_vars=['A', 'B', 'C'],         # 指定要转换的候选键列
    value_name='ID'                     # 转换后的键列名,和df2的ID对应
)

# 步骤3:过滤NaN的ID,和df2做内连接
merged = df1_melted.dropna(subset=['ID']).merge(df2, on='ID', how='inner')

# 步骤4:清理临时列,整理成目标格式
df_output = merged.drop(columns=['variable', 'row_id']).reset_index(drop=True)

print(df_output)

运行后输出结果和你预期的完全一致:

A   B      C  Value
0  1  10  100.0    422
1  1  10  100.0     72
2  2  20    NaN    278
3  3  30  300.0    198

关键细节说明

  • pd.melt的作用是把宽格式的多候选键列“压扁”成单列,这样就能和df2的ID做一对一的匹配,完美解决多列匹配的问题
  • dropna(subset=['ID'])会过滤掉df1中候选键为NaN的行,避免这些NaN尝试和df2的ID匹配(毕竟df2的ID都是有效数值)
  • 使用inner连接可以只保留两边都匹配上的结果,符合你示例中的输出逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 15:07:38