通过 MultiIndex 选择熊猫

Posted

技术标签:

【中文标题】通过 MultiIndex 选择熊猫【英文标题】:Pandas selection by MultiIndex 【发布时间】:2018-06-16 06:36:33 【问题描述】:

关于通过MultiIndex选择行的问题。

df:

              colA   ColB

   A1   B1   1  ca1  cb1
             2  ca2  cb2
        B2   1  ca3  cb3
             2  ca4  cb4 
   A2   B1   1  ca5  cb5
             2  ca6  cb6
        B2   1  ca7  cb7
             2  ca8  cb8

我想从 MultiIndex levels(2) > 1 的 A2/B1 中选择 colA。 我正在分多个步骤进行:

df1=df.loc[A2,[B7],:,]  

出于某种原因,我必须在括号中表示级别(1)

df1.index = x1.index.droplevel(0)

df1.index = x1.index.droplevel(0)

df1.loc[1:,'colA']

我知道这太过分了,但我不知道如何更简单。我能想到的方法不想工作。

【问题讨论】:

How to query MultiIndex index columns values in pandas的可能重复 ^ 上面dupe中的索引是一个命名索引,所以这里不适用。 @Ranny,下次请发布一些可重现的数据。您可以使用df.to_dict() 轻松完成。谢谢! 【参考方案1】:

由于您使用的是未命名的索引列,因此一种方法是在 ilevel_* 上使用 query -

df.query("ilevel_0 == 'A2' and ilevel_1 == 'B1' and ilevel_2 > 1")

        colA ColB
A2 B1 2  ca6  cb6

另一种方法是使用index.get_level_values -

f = df.index.get_level_values
df.loc[(f(0) == 'A2') & (f(1) == 'B1') & (f(2) > 1)]

        colA ColB
A2 B1 2  ca6  cb6

【讨论】:

在我尝试之前。我知道查询有点慢。如果我将名称添加到索引级别会有什么变化? @Ranny 实际上并不多……只是字符串表达式。如果你不想要queryloc 应该很快。 df.index.get_level_values 重命名为f 非常酷! +1 感谢所有帮助。我将使用“f”方法,但会将其他两个保留在武器库中。我只需要摆脱 MultiIndex 的前两个级别。我认为重新索引会做得很好。再次感谢。 @Ranny 不客气。不要忘记对我们的答案进行投票,并接受最有帮助的答案。【参考方案2】:

您也可以在两个操作中执行此操作。首先使用loc 选择A2B1 中的部分,然后通过设置query('index > 1') 对剩余索引进行另一次查询。

df = pd.DataFrame('ColB': ('A1', 'B1', 1): 'cb1',
  ('A1', 'B1', 2): 'cb2',
  ('A1', 'B2', 1): 'cb3',
  ('A1', 'B2', 2): 'cb4',
  ('A2', 'B1', 1): 'cb5',
  ('A2', 'B1', 2): 'cb6',
  ('A2', 'B2', 1): 'cb7',
  ('A2', 'B2', 2): 'cb8',
 'colA': ('A1', 'B1', 1): 'ca1',
  ('A1', 'B1', 2): 'ca2',
  ('A1', 'B2', 1): 'ca3',
  ('A1', 'B2', 2): 'ca4',
  ('A2', 'B1', 1): 'ca5',
  ('A2', 'B1', 2): 'ca6',
  ('A2', 'B2', 1): 'ca7',
  ('A2', 'B2', 2): 'ca8')

# Answer here
df.loc["A2", "B1"].query("index > 1")
Output:
    ColB    colA
 2  cb6     ca6

【讨论】:

我喜欢这个(因为我更了解它)。它有效,只是我需要先对索引进行排序。我唯一不能在引号内传递变量以进行查询。如何做到这一点? a=1; “索引>一个” @Ranny .query("index > @a") @Ranny 混合 locquery 并不像使用两者一样干净。 :-) 谢谢泰。其实我会选择你的解决方案,%timeit 有很大的不同。 3.6 vs 71.6(没有 f 分配)。下次我会记住 .to_dict() 的。 @Ranny Cool。感谢您让我知道您的实验。

以上是关于通过 MultiIndex 选择熊猫的主要内容,如果未能解决你的问题,请参考以下文章

如果存在多索引,熊猫将不允许选择列?

熊猫 iloc 和 loc & multiindex

折叠熊猫 MultiIndex

Pandas 将列多索引转换为行多索引

Pandas 通过 Tuple 重命名 MultiIndex 的单行

KeyError:“未找到元组类型的键且不是 MultiIndex”SVM