2017-01-23 9 views
2

Spalten von Multiindex Datenrahmen mit dem Namen Labels Get:Ich habe in dieser Form ein Datenrahmen

first  bar       foo      
second  one  two  three  one  two  three 
0  -2.008137 0.505892 -0.671299 -1.289395 -1.087887 -0.146657 
1  -0.786329 -0.501268 -1.454408 2.627911 0.689416 -0.877968 
2  -0.697007 0.929783 0.181715 0.533407 0.117859 -0.557975 
3  -1.276656 -0.405381 -0.674329 0.117411 1.536421 0.040912 

Ich möchte mit Indizes Daten auszuwählen, basierend eine Ebene Namen wie folgt aus:

selected = data.xs(('bar', 'two'), level = ['first','second'], axis=1) 

das funktioniert. Allerdings möchte ich auf diese Weise mehrere Labels auswählen. Etwas wie:

selected = data.xs(('bar', ['one','two']), level = ['first','second'], axis=1) 

, um zu erhalten:

first  bar     
second  one  two 
0  -2.008137 0.505892 
1  -0.786329 -0.501268 
2  -0.697007 0.929783 
3  -1.276656 -0.405381 

Dies funktioniert jedoch nicht. Wie kann ich Daten auf diese Weise elegant auswählen? Es ist wichtig, dass ich die Level-Namen ('first' und 'second') verwenden kann.

Antwort

2

können Sie slicers verwenden:

#KeyError: 'MultiIndex Slicing requires the index to be fully lexsorted  
df = df.sort_index(axis=1) 
idx = pd.IndexSlice 
print (df.loc[:, idx['bar', ['one','two']]]) 
first  bar   
second  one  two 
0  -2.008137 0.505892 
1  -0.786329 -0.501268 
2  -0.697007 0.929783 
3  -1.276656 -0.405381 

Eine andere Lösung:

df = df.sort_index(axis=1) 
print (df.loc[:, ('bar', ['one','two'])]) 
first  bar   
second  one  two 
0  -2.008137 0.505892 
1  -0.786329 -0.501268 
2  -0.697007 0.929783 
3  -1.276656 -0.405381 

Aber wenn mit Ebenennamen auswählen müssen verwenden get_level_values mit isin und wählen Sie dann durch boolean indexing (Spalten auswählen, so loc ist notwendig):

mask1 = df.columns.get_level_values('first') == 'bar' 
mask2 = df.columns.get_level_values('second').isin(['one','two']) 
print (df.loc[:, mask1 & mask2]) 
first  bar   
second  one  two 
0  -2.008137 0.505892 
1  -0.786329 -0.501268 
2  -0.697007 0.929783 
3  -1.276656 -0.405381 
+0

Hallo Vielen Dank für Ihre Antwort, aber ich brauche die Ebenennamen zu verwenden (‚ersten‘ und ‚zweiten‘) – Benjamin

+0

Bitte überprüfen bearbeitet Antwort. – jezrael

2

Sie können die query Methode verwenden, aber sie einen Transponieren

data.T.query('first in ["bar", "foo"] and second in ["one", "two"]').T 
# ⤷ transpose here        transpose back ⤴ 

oder Sie diese Variablen außerhalb des query einstellen und Referenz

first = ['bar', 'foo'] 
second = ['one', 'two'] 
data.T.query('first in @first and second in @second').T 
# ⤷ transpose here     transpose back ⤴ 

enter image description here


erfordert Einnahme Heres ein weniger wir ed Alternative zu diesem Problem

data.filter(regex='one|two') 

enter image description here

+0

Hallo Danke für deine Antwort, aber ich muss die Levelnamen ('first' und 'second') verwenden – Benjamin

+0

@Ben Ich habe meinen Beitrag aktualisiert wie jezrael. – piRSquared

Verwandte Themen