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

如何优雅拼接仅保留指定重叠索引层级的MultiIndex DataFrame

优雅拼接MultiIndex DataFrame并保留指定重叠索引层级

我想要一种优雅的方法,拼接多个MultiIndex DataFrame时,仅保留指定索引层级(此处为Level 0:Group、Level 1:Subgroup)的重叠部分,合并它们的Level 2(Category)索引内容。

示例DataFrame

首先定义两个示例DataFrame:

import pandas as pd
import numpy as np

index = pd.MultiIndex.from_product([['A', 'B','C'], ['SubgroupA', 'SubgroupB'], ['X']], names=['Group', 'Subgroup', 'Category'])
df = pd.DataFrame({'Values': np.arange(6)}, index=index)

输出df:

Values
Group Subgroup  Category        
A     SubgroupA X             0
      SubgroupB X             1
B     SubgroupA X             2
      SubgroupB X             3
C     SubgroupA X             4
      SubgroupB X             5

第二个DataFrame:

index2 = pd.MultiIndex.from_product([['B', 'C','D'], ['SubgroupB'], ['A', 'B','C']], names=['Group', 'Subgroup', 'Category'])
df2 = pd.DataFrame({'Values': np.arange(9)}, index=index2)

输出df2:

Values
Group Subgroup  Category        
B     SubgroupB A             0
                B             1
                C             2
C     SubgroupB A             3
                B             4
                C             5
D     SubgroupB A             6
                B             7
                C             8

现有方法的局限

我已实现的方法在处理少量DataFrame时可行,但扩展到多个(比如5个)时需要手动多次调用intersection,代码冗余:

inter = df.index.droplevel(2).intersection(df2.index.droplevel(2)).intersection(df3.index.droplevel(2))  # 需重复追加
pd.concat([df,df2]).loc[(inter.levels[0], inter.levels[1], slice(None))]

优化方案

方案1:用functools.reduce批量计算交集

借助reduce可以自动迭代所有DataFrame的索引片段,一次性求出所有指定层级的交集,完美支持任意数量的DataFrame:

from functools import reduce

# 假设有多个DataFrame,统一存入列表
dfs = [df, df2, df3]  # 可继续追加更多df

# 批量提取每个df去掉Level2的索引,再计算所有交集
inter = reduce(lambda x, y: x.intersection(y), [df.index.droplevel(2) for df in dfs])

# 拼接后筛选出重叠层级的内容
result = pd.concat(dfs).loc[(inter.levels[0], inter.levels[1], slice(None))]
print(result)

方案2:按层级名称处理(更灵活)

如果索引层级的位置可能变化,建议按层级名称操作,避免依赖固定层级位置:

# 按层级名称去掉Category层级,计算交集
inter = reduce(lambda x, y: x.intersection(y), [df.index.droplevel('Category') for df in dfs])

result = pd.concat(dfs).loc[(inter.levels[0], inter.levels[1], slice(None))]

输出结果

以两个示例DataFrame为例,运行优化后的代码会得到:

Values
Group Subgroup  Category        
B     SubgroupB X              3
                A              0
                B              1
                C              2
C     SubgroupB X              5
                A              3
                B              4
                C              5

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 03:54:23