Pandas DataFrame如何检索多索引级别的特定组合

2024-06-24 13:20:12 发布

您现在位置:Python中文网/ 问答频道 /正文

我有以下使用三级多重索引的数据帧:

In [1]: iterables = [[1, 2], ['foo', 'bar'], ['one', 'two']]
   ...: midx = pd.MultiIndex.from_product(iterables)
   ...: df = pd.DataFrame(np.random.randn(8), index=midx)
   ...: df

Out[1]:
                  0
1 foo one -0.217594
      two -1.361612
  bar one  2.477790
      two  0.874409
2 foo one  0.403577
      two  0.076111
  bar one  1.423512
      two  0.047898

我希望对索引进行切片,以便保留第一级的所有内容,同时只保留第二级的以下组合:('foo', 'one')和{}。也就是说,我希望我的输出看起来像这样:

^{pr2}$

例如,是否可以在一行中使用诸如^{}之类的属性来完成这项工作?在


我知道我可以使用^{}函数分别获取所需组合的横截面,但我更喜欢更短、更像切片的语法。具体地说,对于我的用例来说,有一个一行程序是很重要的。在

似乎以下方法应该有效:

df.loc[[(slice(None), 'foo', 'one'), (slice(None), 'bar', 'two')]]

但这会导致TypeError: unhashable type: 'slice'。在


Tags: 数据infromnonedffoobar切片
3条回答

这里有一个基于^{}的解决方案。您的多重索引有未命名的级别,但是级别k可以使用特殊名称ilevel_k访问,根据the docs:“如果{}的级别未命名,则可以使用特殊名称来引用它们。”

query_string = ('(ilevel_1 == "foo" & ilevel_2 == "one") | '
                '(ilevel_1 == "bar" & ilevel_2 == "two")')

df.query(query_string)
                  0
1 foo one -0.217594
  bar two  0.874409
2 foo one  0.403577
  bar two  0.047898

可以通过先删除第一个索引级别,然后使用^{}和元组列表来构造布尔掩码:

df_masked = df[df.index.droplevel(0).isin([('foo', 'one'), ('bar', 'two')])]

print(df_masked)

                  0
1 foo one  1.510316
  bar two  0.260862
2 foo one  0.813745
  bar two  0.023386

jpp和Peter的解决方案很好。如果有人发现它有用,下面是另一种使用序列作为过滤器的方法。在

f = pd.Series([True]*len(midx), index=midx)
f.loc[:,'foo','two'] = False
f.loc[:,'bar','one'] = False

print(df[f[df.index]])
                  0
1 foo one -0.185593
  bar two -1.265191
2 foo one  0.490959
  bar two  0.414753

相关问题 更多 >