通过指定级别的多个值切片MultiIndex DataFrame

时间:2016-08-04 17:46:51

标签: python pandas dataframe multi-index

我想从辅助级别通过多个值切片MultiIndex DataFrame。例如,在以下DataFrame中:

                val1  val2
ind1 ind2 ind3            
1    6    s1      10     8
2    7    s1      20     6
3    8    s2      30     4
4    9    s2      50     2
5    10   s3      60     0

我希望仅切片ind3 == s1 ind3 == s3的行:

           val1  val2
ind1 ind2            
1    6       10     8
2    7       20     6
5    10      60     0

最佳假设选项是将多个参数传递给.xs,因为可以明确说明所需的level

我显然可以将所有切片单值DataFrames连接起来:

In[2]: pd.concat([df.xs('s1',level=2), df.xs('s3',level=2)])
Out[2]:
           val1  val2
ind1 ind2            
1    6       10     8
2    7       20     6
5    10      60     0

但是(a)使用2个以上的值时很乏味且不那么可读,而对于大型DataFrame,(b)它很重(或者至少比多值切片选项(如果存在)。

这是构建示例DataFrame的代码

import pandas as pd
df = pd.DataFrame({'ind1':[1,2,3,4,5], 'ind2':[6,7,8,9,10], 'ind3':['s1','s1','s2','s2','s3'], 'val1':[10,20,30,50,60], 'val2':[8,6,4,2,0]}).set_index(['ind1','ind2','ind3'])

2 个答案:

答案 0 :(得分:11)

与DataFrame中的大多数选择一样,您可以使用掩码或索引器(在这种情况下为loc)。

要获取面具,您可以在MultiIndex上使用get_level_valuesdocs),然后使用isindocs)。

m = df.index.get_level_values('ind3').isin(['s1', 's3'])
df[m].reset_index(level=2, drop=True)

使用loc

df.loc[(slice(None), slice(None), ['s1', 's3']), :].reset_index(level=2, drop=True)

两个输出

           val1  val2
ind1 ind2            
1    6       10     8
2    7       20     6
5    10      60     0

注意:loc方式也可以写成Alberto Garcia-Raboso的回答。许多人更喜欢这种语法,因为它更符合loc的{​​{1}}语法。这两种语法样式都在the docs中讨论。

答案 1 :(得分:7)

您可以使用IndexSlice

idx = pd.IndexSlice
result = df.loc[idx[:, :, ['s1', 's3']], idx[:]]
result.index = result.index.droplevel('ind3')
print(result)

输出:

           val1  val2
ind1 ind2            
1    6       10     8
2    7       20     6
5    10      60     0

上面第二行也可以写成

result = df.loc(axis=0)[idx[:, :, ['s1', 's3']]]