2017-10-07 2 views
3

Ich habe einen Multiindex Datenrahmen wie folgt aus:Warum sehe ich alle ursprünglichen Indexelemente in einem geschnittenen Datenframe?

import pandas as pd 
import numpy as np 


df = pd.DataFrame({'ind1': list('aaaaaaaaabbbbbbbbb'), 
        'ind2': list('cccdddeeecccdddeee'), 
        'ind3': list(range(3))*6, 
        'val1': list(range(100, 118)), 
        'val2': list(range(70, 88))}) 

df_mult = df.set_index(['ind1', 'ind2', 'ind3']) 

       val1 val2 
ind1 ind2 ind3    
a c 0  100 70 
      1  101 71 
      2  102 72 
    d 0  103 73 
      1  104 74 
      2  105 75 
    e 0  106 76 
      1  107 77 
      2  108 78 
b c 0  109 79 
      1  110 80 
      2  111 81 
    d 0  112 82 
      1  113 83 
      2  114 84 
    e 0  115 85 
      1  116 86 
      2  117 87 

ich jetzt eine Teilmenge davon mit .loc wie diese

df_subs = df_mult.loc[pd.IndexSlice['a', ['c', 'd'], :], :] 

auswählen können, die die

   val1 val2 
ind1 ind2 ind3    
a c 0  100 70 
      1  101 71 
      2  102 72 
    d 0  103 73 
      1  104 74 
      2  105 75 

Wenn ich erwartet gibt drucken

df_subs.index 

ich

MultiIndex(levels=[[u'a', u'b'], [u'c', u'd', u'e'], [0, 1, 2]], 
      labels=[[0, 0, 0, 0, 0, 0], [0, 0, 0, 1, 1, 1], [0, 1, 2, 0, 1, 2]], 
      names=[u'ind1', u'ind2', u'ind3']) 

Warum immer noch ist es b in der Ebene 0 und nicht nur a?

Dies könnte ein Problem werden, wenn ich die Elemente des Index für etwas anderes verwenden möchte. Dann

df_subs.index.levels[0] 

gibt mir

Index([u'a', u'b'], dtype='object', name=u'ind1') 

jedoch

df_subs.index.get_level_values('ind1').unique() 

gibt mir

Index([u'a'], dtype='object', name=u'ind1') 

die mir inkonsistent aussieht.

Ist dies ein Fehler oder ein beabsichtigtes Verhalten?

+1

ich, warum auch wissen will :) – Wen

Antwort

3

Es gibt eine Diskussion über GitHub, die dieses Verhalten umgibt here.

Kurz gesagt, die Ebenen, die Sie sehen, werden nicht aus den Werten im MultiIndex berechnet, die Sie tatsächlich beobachten - unbeobachtete Ebenen bleiben durch Indizierung bestehen, nachdem Sie den MultiIndex zum ersten Mal eingerichtet haben. Dies ermöglicht, dass die Ebenenindizes zwischen allen Ansichten und Kopien von einigen MultiIndex geteilt werden, was nett Speicher ist - d. H. df_mult und df_subs teilen sich die gleichen zugrunde liegenden Ebenenindizes im Speicher.

Wenn Sie einen Fall haben, für den Sie die Ebenen neu berechnen möchten, um die unbenutzten zu entfernen und einen neuen MultiIndex zu erstellen, können Sie MultiIndex.remove_unused_levels() verwenden.

In Ihrem Fall

>>> df_subs.index.remove_unused_levels().levels[0] 
Index(['a'], dtype='object', name='ind1') 
+1

Anmerkung Leser tun: 'MultiIndex.remove_unused_levels()' ist eine * neu * Methode in Pandas ab Version 20. – Parfait

Verwandte Themen