2013-08-27 59 views
11

我有一个多指标列数据框,看起来像这样:如何仅使用MultiIndex列从DataFrame中选择特定列?

# sample data 
col = pd.MultiIndex.from_arrays([['one', 'one', 'one', 'two', 'two', 'two'], 
           ['a', 'b', 'c', 'a', 'b', 'c']]) 
data = pd.DataFrame(np.random.randn(4, 6), columns=col) 
data 

sample data

什么是从第二级只选择特定的列(如['a', 'c'],而不是一个区间)的合适的,简单的方法?

目前,我这样做是这样的:

import itertools 
tuples = [i for i in itertools.product(['one', 'two'], ['a', 'c'])] 
new_index = pd.MultiIndex.from_tuples(tuples) 
print(new_index) 
data.reindex_axis(new_index, axis=1) 

expected result

它不觉得自己是一个很好的解决方案,但是,因为我已经出局itertools,手工打造的又一多指标和然后reindex(和我的实际代码更混乱,因为列列表并不是很容易获取)。我很确定必须有一些ixxs这样做,但我试过的一切都会导致错误。

+0

您是否尝试过使用字典? – darmat

+0

不,我没有。你的意思是更快地构建MultiIndex?如果是这样,那不是重点 - 我想避免它,并直接用像'data.xs(['a','c'],axis = 1,level = 1)'这样的东西编号' – metakermit

+0

让我们假设: – darmat

回答

6

这不是很大,但也许:

>>> data 
     one       two      
      a   b   c   a   b   c 
0 -0.927134 -1.204302 0.711426 0.854065 -0.608661 1.140052 
1 -0.690745 0.517359 -0.631856 0.178464 -0.312543 -0.418541 
2 1.086432 0.194193 0.808235 -0.418109 1.055057 1.886883 
3 -0.373822 -0.012812 1.329105 1.774723 -2.229428 -0.617690 
>>> data.ix[:,data.columns.get_level_values(1).isin({"a", "c"})] 
     one     two   
      a   c   a   c 
0 -0.927134 0.711426 0.854065 1.140052 
1 -0.690745 -0.631856 0.178464 -0.418541 
2 1.086432 0.808235 -0.418109 1.886883 
3 -0.373822 1.329105 1.774723 -0.617690 

会的工作?

+0

其实我认为这是在MultiIndex的任意级别过滤出标签列表而不创建所有元组的最佳方式。我只是为了清晰起见而使用'loc'。 –

+0

要保留列的顺序,最好使用'isin([“a”,“b”])'。 – Peaceful

+0

@和平:什么?这并没有改变任何东西。 isin调用的结果是一个bool系列,其顺序由原始系列的顺序决定,而不是isin的参数。 – DSM

8

您可以使用,locix我将展示与loc一个例子:

data.loc[:, [('one', 'a'), ('one', 'c'), ('two', 'a'), ('two', 'c')]] 

当你有一个MultiIndexed数据帧,并且要过滤出一些列的,你必须传递与这些列匹配的元组列表。所以迭代工具的做法是非常好的,但是你没有创建一个新的多指标:

data.loc[:, list(itertools.product(['one', 'two'], ['a', 'c']))] 
+0

谢谢,这也是一个很好的解决方案! – metakermit

13

我认为这是一个更好的方法(现在的),这就是为什么我懒得拉这个问题(这是前谷歌结果)走出阴影:

data.select(lambda x: x[1] in ['a', 'b'], axis=1) 

给出您的预计产量在快速,干净的一行:

 one     two   
      a   b   a   b 
0 -0.341326 0.374504 0.534559 0.429019 
1 0.272518 0.116542 -0.085850 -0.330562 
2 1.982431 -0.420668 -0.444052 1.049747 
3 0.162984 -0.898307 1.762208 -0.101360 

它基本上是自我解释,该[1]指水平。

4

要选择你的列索引的第二级命名'a''c'所有列,您可以用切片机:

>>> data.loc[:, (slice(None), ('a', 'c'))] 

     one     two   
      a   c   a   c 
0 -0.983172 -2.495022 -0.967064 0.124740 
1 0.282661 -0.729463 -0.864767 1.716009 
2 0.942445 1.276769 -0.595756 -0.973924 
3 2.182908 -0.267660 0.281916 -0.587835 

Here你可以阅读更多有关切片机。

相关问题