2016-04-14 6 views
2

Ich habe einen DataFrame, df1, die ein Stück df ist. df ist multiindiziert und hat die Form (8,). Die Schicht entfernt einige der zweiten Ebene von df. Wenn ich df1.shape mache, gibt es (4,) zurück - alles gut - aber wenn ich df1.index.levels[0] mache, gibt das (4,) zurück. Wie kommt es dazu?Warum unterscheidet sich der Index eines Pandas DataFrame Slice von seiner Form?

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 

Jetzt für die seltsame Bit

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,) 

Ich finde das seltsam, da es keine bar in df1 gezeigt ist. Was ist der Grund dafür?

Meine Vermutung ist, dass es etwas mit dem Kopieren/nicht Kopieren zu tun hat, aber ich verstehe nicht warum.

Antwort

3

Per der docs:

Hinweis Die repr eines Multiindex zeigt alle definierten Ebenen eines Index, auch wenn die sie nicht tatsächlich verwendet wird. Wenn Sie einen Index in Scheiben schneiden, können Sie dies bemerken. ...

Dies wird gemacht, um eine Neuberechnung der Ebenen zu vermeiden, um das Schneiden hochperformant zu machen. Wenn Sie die tatsächlich verwendeten Ebenen sehen möchten ...

Um den Multiindex nur mit den verwendeten Ebenen

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

I Ich denke, Ich wusste nicht genug über Multiindexing zu denken, um dort zu suchen oder wissen, wofür man so vielen Dank suchen! – josh

2

Betrachten wir die beiden Indizes:

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]]) 

Wann bauen df1 mit df1 = df[df[1]>0] Pandas die labels wechselnden df1.index von nur bauen. Darüber hinaus, wenn es die levels nicht ändert, dann muss es die labels nicht neu nummerieren. Deshalb enthält df1.indexbar , obwohl df1bar nicht verwendet.

können Sie den Index neu aufbauen, indem reset_index/set_index mit:

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']) 

- oder Alexander's faster solution verwenden, df1.index = pd.MultiIndex.from_tuples(df1.index) - aber Pandas ist dies wahrscheinlich für eine bessere Leistung standardmäßig nicht.

1

Es ist zu rekonstruieren, weil die Ebenen nur die Etiketten sind, ist es die zweite Pegelwerte ist, die die Etiketten vorhanden sind für das Etikett bestimmen, so zum Beispiel in mein Fall:

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]]) 

gibt:

In [4]: 
df1 

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

Also, wenn Sie auf der Index aussehen:

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

die Werte: labels=[[0, 0, 1], [0, 1, 0] die Werte aus den Pegelwerte sind, die vorhanden sind, weshalb Sie alle 4-Etiketten zu sehen und die Form ist 4

+0

Nur aus Gründen der Übersichtlichkeit entsprechen die ersten Teilbezeichungen "labels = [[0,0,1], ...]" der Aussage "die Multiindex-Ebene 0 ist' ['bar', 'bar', 'baz' ] '"? – josh

+1

Ja das ist richtig, es ist ein Index, um die Ebenen zu referenzieren – EdChum

Verwandte Themen