2017-01-23 49 views
2

我在这个形式的数据帧:获得来自多指标数据框中列名为标签

first  bar       foo      
second  one  two  three  one  two  three 
0  -2.008137 0.505892 -0.671299 -1.289395 -1.087887 -0.146657 
1  -0.786329 -0.501268 -1.454408 2.627911 0.689416 -0.877968 
2  -0.697007 0.929783 0.181715 0.533407 0.117859 -0.557975 
3  -1.276656 -0.405381 -0.674329 0.117411 1.536421 0.040912 

我想基于一个级别名称这样的指标来选择数据:

selected = data.xs(('bar', 'two'), level = ['first','second'], axis=1) 

这个工程。不过,我想以这种方式选择多个标签。喜欢的东西:

selected = data.xs(('bar', ['one','two']), level = ['first','second'], axis=1) 

为了得到:

first  bar     
second  one  two 
0  -2.008137 0.505892 
1  -0.786329 -0.501268 
2  -0.697007 0.929783 
3  -1.276656 -0.405381 

然而,这是行不通的。我怎样才能以这种方式优雅地选择数据?重要的是我可以使用关卡名称('第一'和'第二')。

回答

2

您可以使用slicers

#KeyError: 'MultiIndex Slicing requires the index to be fully lexsorted  
df = df.sort_index(axis=1) 
idx = pd.IndexSlice 
print (df.loc[:, idx['bar', ['one','two']]]) 
first  bar   
second  one  two 
0  -2.008137 0.505892 
1  -0.786329 -0.501268 
2  -0.697007 0.929783 
3  -1.276656 -0.405381 

另一种解决方案:

df = df.sort_index(axis=1) 
print (df.loc[:, ('bar', ['one','two'])]) 
first  bar   
second  one  two 
0  -2.008137 0.505892 
1  -0.786329 -0.501268 
2  -0.697007 0.929783 
3  -1.276656 -0.405381 

但是,如果需要与级别名称选择使用带有isinget_level_values然后boolean indexing选择(选择列,所以loc是必要的):

mask1 = df.columns.get_level_values('first') == 'bar' 
mask2 = df.columns.get_level_values('second').isin(['one','two']) 
print (df.loc[:, mask1 & mask2]) 
first  bar   
second  one  two 
0  -2.008137 0.505892 
1  -0.786329 -0.501268 
2  -0.697007 0.929783 
3  -1.276656 -0.405381 
+0

你好谢谢你的答案,但我需要使用级别名称(“第一”和“第二”) – Benjamin

+0

请检查编辑答案。 – jezrael

2

可以使用query方法,但需要采取转置

data.T.query('first in ["bar", "foo"] and second in ["one", "two"]').T 
# ⤷ transpose here        transpose back ⤴ 

可以设置query之外的变量,并引用它们

first = ['bar', 'foo'] 
second = ['one', 'two'] 
data.T.query('first in @first and second in @second').T 
# ⤷ transpose here     transpose back ⤴ 

enter image description here


继承人少了我们编辑替代这个问题

data.filter(regex='one|two') 

enter image description here

+0

嗨感谢您的回答,但我需要使用关卡名称('第一'和'第二') – Benjamin

+0

@Ben我已更新我的帖子,因为jezrael。 – piRSquared