2014-06-26 30 views
3

比方說,我有一個很大的數據框large,它在行上有一個MultiIndex。我通過只選擇一些行並將結果分配給small來削減這個數據幀。特別地,small在其行的MultiIndex的第0級具有比large更少的不同值。DataFrame.index.levels在削減數據框後顯示「額外」值

然後我想要在small行的MultiIndex的第0級別中的不同值的列表,所以我打電話small.index.levels[0]。結果很奇怪:它返回的結果與large.index.levels[0]相同,儘管應該有更少的值。

發生了什麼事?

MWE:

import pandas as pd 
import numpy as np 

np.random.seed(0) 

idx = pd.MultiIndex.from_product([['John', 'Josh', 'Alex'], list('abcde')], 
           names=['Person', 'Letter']) 
large = pd.DataFrame(data=np.random.randn(15, 2), 
        index=idx, 
        columns=['one', 'two']) 
small = large.loc[['Jo'==d[0:2] for d in large.index.get_level_values('Person')]] 

print small.index.levels[0] 
print large.index.levels[0] 

輸出:

Index([u'Alex', u'John', u'Josh'], dtype='object') 
Index([u'Alex', u'John', u'Josh'], dtype='object') 

預期輸出:

Index([u'John', u'Josh'], dtype='object') 
Index([u'Alex', u'John', u'Josh'], dtype='object') 

回答

2

更有效地做到這一點。

In [43]: large[large.index.get_level_values('Person').to_series().str.startswith('Jo').values] 
Out[43]: 
        one  two 
Person Letter      
John a  1.764052 0.400157 
     b  0.978738 2.240893 
     c  1.867558 -0.977278 
     d  0.950088 -0.151357 
     e  -0.103219 0.410599 
Josh a  0.144044 1.454274 
     b  0.761038 0.121675 
     c  0.443863 0.333674 
     d  1.494079 -0.205158 
     e  0.313068 -0.854096 

回答你的問題。這是一個實現細節。使用.get_level_values()(而不是訪問內部.levels

,如果你想你可以做到這一點。

In [13]: small.index.get_level_values('Person').unique() 
Out[13]: array(['John', 'Josh'], dtype=object) 

In [14]: large.index.get_level_values('Person').unique() 
Out[14]: array(['John', 'Josh', 'Alex'], dtype=object) 
+0

我不太清楚你已經回答了我的問題。我的目標是不是爲了實現從'過濾大「到」small「,我的'small'上面只有我想要的數據,我想要的是在'small'的MultiIndex的第0級獲得不同值的列表(例如,'large'在其MultiIndex的'Person'級別可能有數百個名字,所以我可能不知道當我過濾掉只以'Jo''開頭的名字時我會得到什麼,但是,一旦過濾完成,我想看看我得到了什麼,你如何建議我這樣做? – 8one6

+0

使用''.unique()'' – Jeff