Pandas两个多层索引DataFrame合并如何获取索引并集?
多索引DataFrame合并丢失索引问题解决
问题背景
需要合并两个带有多层索引的pandas DataFrame,要求保留两个表所有的索引(即索引的并集),缺失字段填充NaN。
测试场景示例
- df1结构:
import pandas as pd import numpy as np row_x1 = ['a1','b1','c1'] row_x2 = ['a2','b2','c2'] row_x3 = ['a3','b3','c3'] row_x4 = ['a4','b4','c4'] index_arrays = [np.array(['first', 'first', 'second', 'second']), np.array(['one','two','one','two'])] df1 = pd.DataFrame([row_x1,row_x2,row_x3,row_x4], columns=list('ABC'), index=index_arrays)
输出:
A B C first one a1 b1 c1 two a2 b2 c2 second one a3 b3 c3 two a4 b4 c4
- df2结构:
row_y1 = ['d1','e1','f1'] row_y2 = ['d2','e2','f2'] row_y3 = ['d3','e3','f3'] index_arrays = [np.array(['first','first', 'second',]), np.array(['one','three','two'])] df2 = pd.DataFrame([row_y1,row_y2,row_y3], columns=list('DEF'), index=index_arrays)
输出:
D E F first one d1 e1 f1 three d2 e2 f2 second two d3 e3 f3
- 期望合并结果df3:
A B C D E F first one a1 b1 c1 d1 e1 f1 two a2 b2 c2 NaN NaN NaN three NaN NaN NaN d2 e2 f2 second one a3 b3 c3 NaN NaN NaN two a4 b4 c4 d3 e3 f3
实际遇到的问题
动态生成的两个多层索引DataFrame执行merge外连接时,单侧独有的索引丢失:
df1.merge(df2, left_index=True, right_index=True, how='outer')
上述代码执行后,df2中独有的索引6没有出现在合并结果中,无法提前判断哪个表的索引更多,需要通用的合并方案。
解决方案
方案1:优先使用pd.concat按列拼接(推荐)
对于按索引对齐的多表列拼接场景,pd.concat原生支持保留索引并集,不需要额外参数适配,代码更简洁:
df_merged = pd.concat([df1, df2], axis=1)
该方法会自动对齐多层索引,保留所有出现过的索引值,缺失字段自动填充NaN,完全符合需求。
方案2:修复merge的使用问题
你遇到的索引丢失问题是旧版本pandas处理带NaN的多层索引外连接的已知bug,可通过以下两种方式修复:
- 升级pandas到1.3.0及以上版本,官方已修复该问题,原有
merge代码可正常返回完整结果。 - 若无法升级版本,可先将索引转为普通列再合并,完成后重新设置索引:
# 重置索引为普通列 df1_reset = df1.reset_index() df2_reset = df2.reset_index() # 按原索引字段外连接 merged_temp = df1_reset.merge(df2_reset, on=['level_0', 'level_1'], how='outer') # 恢复多层索引 df_merged = merged_temp.set_index(['level_0', 'level_1'])
两种方案都不需要提前判断两个表的索引范围,适配动态生成的DataFrame场景。
内容的提问来源于stack exchange,提问作者jia chuan
相关产品推荐
相关产品推荐

