2016-04-14 70 views
2

我有一個DataFrame,df1,它是df的一部分。 df是多索引並且形狀(8,)。切片刪除了一些第二級df。當我做df1.shape它返回(4,) - 一切都好 - 但是當我做df1.index.levels[0]這將返回(4,)。這是怎麼發生的?爲什麼熊貓數據框切片的索引與其形狀不同?

In [ ]:  
arrays = [np.array(['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux']), 
      np.array(['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two'])] 


    df = pd.DataFrame(np.random.randn(8,2), index=arrays) 
    df 

Out [ ]: 
      0  1 
bar one -0.447155 -0.323073 
    two 0.115899 -0.015561 
baz one -0.272498 1.847073 
    two -0.399948 -0.264327 
foo one 0.169687 -1.708543 
    two 1.154434 0.878936 
qux one 0.535721 0.437186 
    two -1.203431 0.568412 

In [ ]: 
    df1=df[df[1]>0] 

Out [ ]: 
      0   1 
    baz one -0.272498 1.847073 
    foo two 1.154434 0.878936 
    qux one 0.535721 0.437186 
     two -1.203431 0.568412 

現在的怪異位

In [ ]: 
    df1=df[df[1]>0] 
    print(df1.index.levels[0], df1.index.levels[0].shape) 

Out [ ]: 
    Index(['bar', 'baz', 'foo', 'qux'], dtype='object') (4,) 

我覺得這很奇怪,因爲沒有在df1所示bar。這背後的原因是什麼?

我的猜測是這是與複製/不復制,但我不明白爲什麼。

回答

3

docs

注意一個多指標的再版顯示索引的所有定義的水平,即使未實際使用他們。切片索引時,您可能會注意到這一點。 ...

這樣做是爲了避免重新計算級別,以使切片具有高性能。如果你想看到實際使用的水平...

成僅僅在使用層面重建多指標

df1.index = pd.MultiIndex.from_tuples(df1.index) 
+0

我想我不知道多重索引是否想要在那裏尋找,或知道要尋找什麼,以致非常感謝! – josh

2

考慮兩個指標:

In [59]: df.index 
Out[59]: 
MultiIndex(levels=[[u'bar', u'baz', u'foo', u'qux'], [u'one', u'two']], 
      labels=[[0, 0, 1, 1, 2, 2, 3, 3], [0, 1, 0, 1, 0, 1, 0, 1]]) 

In [58]: df1.index 
Out[58]: 
MultiIndex(levels=[[u'bar', u'baz', u'foo', u'qux'], [u'one', u'two']], 
      labels=[[1, 2, 3, 3], [0, 1, 0, 1]]) 

df1 = df[df[1]>0]熊貓建設df1可以建立df1.index通過 僅僅改變labels。此外,如果它不更改levels,那麼 它不必重新編號labels。這就是爲什麼df1.index包含bar 即使df1不使用bar

您可以通過使用reset_index/set_index重建索引:

In [63]: df1.reset_index().set_index(['level_0', 'level_1']).index 
Out[63]: 
MultiIndex(levels=[[u'baz', u'foo', u'qux'], [u'one', u'two']], 
      labels=[[0, 1, 2, 2], [0, 1, 0, 1]], 
      names=[u'level_0', u'level_1']) 

- 或使用Alexander's faster solutiondf1.index = pd.MultiIndex.from_tuples(df1.index) - 但熊貓 默認情況下並不可能獲得更好的性能做到這一點。

1

這是因爲該水平只是標籤,它的第二級值確定哪些標籤存在該標籤,所以例如在我的情況:

In [2]: 
arrays = [np.array(['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux']), 
      np.array(['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two'])] 
​ 
df = pd.DataFrame(np.random.randn(8,2), index=arrays) 
df 
​ 
Out[2]: 
       0   1 
bar one 1.226303 0.017598 
    two 0.940893 1.491474 
baz one 0.335430 1.178512 
    two -1.006346 -0.733090 
foo one -0.765838 -0.494056 
    two -1.744994 -1.001641 
qux one 0.177123 -0.969671 
    two 0.544314 -0.026114 

In [3]:  
df1=df[df[1]>0] 
df1.index 

Out[3]: 
MultiIndex(levels=[['bar', 'baz', 'foo', 'qux'], ['one', 'two']], 
      labels=[[0, 0, 1], [0, 1, 0]]) 

給出:

In [4]: 
df1 

Out[4]: 
       0   1 
bar one 1.226303 0.017598 
    two 0.940893 1.491474 
baz one 0.335430 1.178512 

所以,如果你看一下指數:

MultiIndex(levels=[['bar', 'baz', 'foo', 'qux'], ['one', 'two']], 
       labels=[[0, 0, 1], [0, 1, 0]]) 

值:labels=[[0, 0, 1], [0, 1, 0]是從存在的電平值的值這就是爲什麼你看到所有4個標籤和形狀是4

+0

只是爲了清楚起見,第一部分標籤'labels = [[0,0,1],...]'等同於表示「Multiindex等級0是'['bar','bar','baz' ]'「? – josh

+1

是的,這是正確的,它是一個參考級別的索引 – EdChum