如何优雅拼接仅保留指定重叠索引层级的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
相关产品推荐
相关产品推荐

