2016-07-23 13 views
1

Angenommen, Sie haben einen Panda DataFrame mit einem MultiIndex. Sie möchten alle Zeilen mit einem Label mit einem bestimmten Wert abrufen. Wie machst Du das?Pandas MultiIndex erhält alle Zeilen mit Label-Wert

Mein erster Gedanke war eine boolean Maske ...

df[df.index.labels == 1].head()

aber das funktioniert nicht.

Danke!

+0

Sie können den Index zurück in Spalten konvertieren und anschließend filtern. Es funktioniert sicherlich mit einem Index. Es sollte mit Multiindex funktionieren, aber ich bin mir nicht sicher. –

+2

Zeigen Sie den Datenrahmen an, mit dem Sie arbeiten. – Merlin

+0

Warum der Downvote? Ist das irgendwo klar dokumentiert? Ist es unklar? Ist es nicht hilfreich? Es hätte mir offensichtlich geholfen http://meta.stackoverflow.com/questions/252677/when-is-it-juditable-to-downvote-a-question –

Antwort

2

Sie müssen angeben, welchen Index Sie verwenden. In meinem Beispiel habe ich der zweite Index (My Datenrahmen s ist, weil es so in Multiindex Seite von Pandas war):

s[s.index.labels[1]==1] 

können Sie tatsächlich sehen, wie Index, wenn Sie Typ aufgebaut ist:

s.index 

die resultierende Struktur ist:

MultiIndex(levels=[['bar', 'baz', 'foo', 'qux'], [1, 2]], 
     labels=[[0, 0, 1, 1, 2, 2, 3, 3], [0, 1, 0, 1, 0, 1, 0, 1]], 
     names=['first', 'second']) 

Below ich habe den vollständigen Code:

>>> import pandas as pd 
>>> import numpy as np 
>>> arrays = [['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'], 
...   [1, 2, 1, 2, 1, 2, 1, 2]] 
... 
>>> tuples = list(zip(*arrays)) 
>>> index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second']) 
>>> s = pd.Series(np.random.randn(8), index=index) 
>>> s[s.index.labels[1]==1] 
first second 
bar 2  -0.304029 
baz 2  -1.216370 
foo 2   1.401905 
qux 2  -0.411468 
dtype: float64 
1

würde ich xs (cross-section) verwenden:

In [11]: df = pd.DataFrame([[1, 2, 3], [3, 4, 5]], columns=list("ABC")).set_index(["A", "B"]) 

In [12]: df 
Out[12]: 
    C 
A B 
1 2 3 
3 4 5 

dann können Sie diejenigen treffen, die Pegel haben A gleich 1:

In [13]: df.xs(key=1, level="A") 
Out[13]: 
    C 
B 
2 3 

Mit drop_level=False funktioniert der Filter (ohne die A-Index zu fallen):

In [14]: df.xs(key=1, level="A", drop_level=False) 
Out[14]: 
    C 
A B 
1 2 3 
0

Alternativlösung:

In [62]: df = pd.DataFrame({'idx1': ['A','B','C'], 'idx2':[1,2,3], 'val': [30,10,20]}).set_index(['idx1','idx2']) 

In [63]: df 
Out[63]: 
      val 
idx1 idx2 
A 1  30 
B 2  10 
C 3  20 

In [64]: df[df.index.get_level_values('idx2') == 2] 
Out[64]: 
      val 
idx1 idx2 
B 2  10 

In [65]: df[df.index.get_level_values(1) == 2] 
Out[65]: 
      val 
idx1 idx2 
B 2  10