部分级别上的 pandas MultiIndex 交集

Posted

技术标签:

【中文标题】部分级别上的 pandas MultiIndex 交集【英文标题】:pandas MultiIndex intersection on partial levels 【发布时间】:2022-01-04 09:14:03 【问题描述】:

假设我有两个带有多索引的数据框,其中一个索引比另一个更深。现在我想从一个(更深的)数据框中只选择那些行,其中它们的部分索引包含在另一个数据框中。

示例输入:

df = pandas.DataFrame(
    
        "A": ["a1", "a1", "a1", "a2", "a2", "a2"],
        "B": ["b1", "b1", "b2", "b1", "b2", "b2"],
        "C": ["c1", "c2", "c1", "c1", "c1", "c2"],
        "V": [1, 2, 3, 4, 5, 6],
     
).set_index(["A", "B", "C"])
df2 = pandas.DataFrame(
    
        "A": ["a1", "a1", "a2", "a2"],
        "B": ["b1", "b3", "b1", "b3"],
        "X": [1, 2, 3, 4]
     
).set_index(["A", "B"])

视觉:

          V
A  B  C
a1 b1 c1  1
      c2  2
   b2 c1  3
a2 b1 c1  4
   b2 c1  5
      c2  6

       X
A  B
a1 b1  1
   b3  2
a2 b1  3
   b3  4

期望的输出:

result = pandas.DataFrame(
    
        "A": ["a1", "a1", "a2"],
        "B": ["b1", "b1", "b1"],
        "C": ["c1", "c2", "c1"],
        "V": [1, 2, 4],
     
).set_index(["A", "B", "C"])

视觉:

          V
A  B  C
a1 b1 c1  1
      c2  2
a2 b1 c1  4

我试过了 df.loc[df2.index]df.loc[df.index.intersection(df2.index)] 但这不起作用。

我想我可以做df.join(df2, how="inner") 然后删除所有添加的df2 列,但这很麻烦。或者有没有办法把df2的列全部去掉?

我将不胜感激。

【问题讨论】:

【参考方案1】:

一种选择是在两者共有的特定标签上使用isin,并使用生成的布尔值来过滤df

df.loc[df.index.droplevel('C').isin(df2.index)]
 
          V
A  B  C    
a1 b1 c1  1
      c2  2
a2 b1 c1  4

【讨论】:

以上是关于部分级别上的 pandas MultiIndex 交集的主要内容,如果未能解决你的问题,请参考以下文章

将多个键上的 pandas 数据帧映射为列或 multiIndex

在 Pandas 中将两个 MultiIndex 级别合并为一个

Pandas Multiindex 系列级别重新索引

Pandas DataFrame - 如何检索 MultiIndex 级别的特定组合

带有 pandas groupby multiindex 的箱线图,用于来自 multiindex 的指定子级别

在 pandas DataFrame 中重新排序 MultiIndex 的级别