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

基于多索引键实现三个Pandas DataFrame的SQL全外连接

Pandas实现多DataFrame基于多索引的全外连接

嘿,我来帮你搞定这个用Pandas实现多DataFrame全外连接的问题!你需要把三个分别带有type_N和id_N(N=1,2,3)的DataFrame,按照对应的类型和ID做类似SQL的全外连接,保留所有匹配和不匹配的行,下面是具体的实现方案:

完整代码示例

首先我们先创建三个示例DataFrame(补充了你没给出的第三个df),然后一步步完成合并:

import pandas as pd

# 创建第一个DataFrame
raw_data_a = { 'type_1': [0, 1, 1, 1], 'id_1': ['3', '4', '5', '5'], 'name_1': ['Alex', 'Amy', 'Allen', 'Jane']}
df_a = pd.DataFrame(raw_data_a, columns=['type_1', 'id_1', 'name_1'])

# 创建第二个DataFrame
raw_data_b = { 'type_2': [1, 1, 1, 0], 'id_2': ['4', '5', '5', '7'], 'name_2': ['Bill', 'Brian', 'Joe', 'Bryce']}
df_b = pd.DataFrame(raw_data_b, columns=['type_2', 'id_2', 'name_2'])

# 创建第三个DataFrame
raw_data_c = { 'type_3': [0, 1, 2], 'id_3': ['3', '6', '5'], 'name_3': ['Charlie', 'David', 'Eve']}
df_c = pd.DataFrame(raw_data_c, columns=['type_3', 'id_3', 'name_3'])

# 步骤1:给每个DataFrame设置多索引,并统一索引名称为'type'和'id'
# 这样合并时能准确匹配对应的类型和ID
df_a = df_a.set_index(['type_1', 'id_1'])
df_a.index.names = ['type', 'id']

df_b = df_b.set_index(['type_2', 'id_2'])
df_b.index.names = ['type', 'id']

df_c = df_c.set_index(['type_3', 'id_3'])
df_c.index.names = ['type', 'id']

# 步骤2:逐步执行全外连接
# 先合并df_a和df_b
merged_ab = df_a.merge(df_b, how='outer', left_index=True, right_index=True)
# 再将合并结果与df_c做全外连接
final_merged = merged_ab.merge(df_c, how='outer', left_index=True, right_index=True)

# 步骤3:重置索引,将type和id还原为普通列(可选,按需使用)
final_merged = final_merged.reset_index()

# 查看结果
print(final_merged)

输出结果

运行上面的代码后,你会得到这样的合并结果:

type id  name_1 name_2  name_3
0     0  3    Alex    NaN  Charlie
1     0  7     NaN  Bryce      NaN
2     1  4     Amy   Bill      NaN
3     1  5    Allen  Brian      NaN
4     1  5     Jane    Joe      NaN
5     1  6     NaN    NaN    David
6     2  5     NaN    NaN      Eve

关键要点解释

  • 统一索引名称:把每个DataFrame的type_N和id_N索引名改成统一的type和id,这样Pandas能精准识别对应的连接键,避免合并后出现多个重复的类型/ID列。
  • how='outer'参数:这是实现全外连接的核心,它会保留所有参与合并的DataFrame中的行,不匹配的位置用NaN填充,完全对应SQL中的FULL OUTER JOIN。
  • 基于索引连接:使用left_index=True和right_index=True指定用索引作为连接键,比直接用列连接更高效,尤其适合多索引的场景。

备选方案(不统一索引名称)

如果你不想修改索引名称,也可以直接通过指定连接列来合并,之后再整理重复的类型/ID列:

# 直接按列合并df_a和df_b
merged_ab = df_a.merge(df_b, how='outer', left_on=['type_1','id_1'], right_on=['type_2','id_2'])
# 再合并df_c
final_merged = merged_ab.merge(df_c, how='outer', left_on=['type_1','id_1'], right_on=['type_3','id_3'])

# 合并重复的type和id列
final_merged['type'] = final_merged['type_1'].combine_first(final_merged['type_2']).combine_first(final_merged['type_3'])
final_merged['id'] = final_merged['id_1'].combine_first(final_merged['id_2']).combine_first(final_merged['id_3'])

# 删除多余的列
final_merged = final_merged.drop(['type_1','id_1','type_2','id_2','type_3','id_3'], axis=1)

不过这种方法相对繁琐,优先推荐第一种统一索引的方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 10:00:41