2016-10-05 12 views
8

mam ramki danych o indeksie (year, foo), gdzie mi się podoba wybrać X największe obserwacje foo gdzie year == someYear.MultiIndex Odcinanie wymaga indeks zostanie całkowicie lexsorted

Moje podejście było

df.sort_index(level=[0, 1], ascending=[1, 0], inplace=True) 
df.loc[pd.IndexSlice[2002, :10], :] 

ale mam

KeyError: 'MultiIndex Slicing requires the index to be fully lexsorted tuple len (2), lexsort depth (0)' 

Próbowałem różne warianty sortowania (np ascending = [0, 0]), ale wszystkie one doprowadziły do ​​jakiegoś błędu.

Jeśli chcę tylko wiersz xth, mogę po sortowaniu uzyskać df.groupby(level=[0]).nth(x), ale ponieważ chcę zestaw wierszy, to nie wydaje się dość skuteczne.

Jaki jest najlepszy sposób wyboru tych wierszy? Niektóre dane grać z:

    rank_int rank 
year foo       
2015 1.381845    2 320 
    1.234795    2 259 
    1.148488   199  2 
    0.866704    2 363 
    0.738022    2 319 
+0

Co się stanie, jeśli po prostu posortujesz używając 'df.sort_index (inplace = True)'? – ASGM

+0

@ASGM To działa, ale skoro nie jestem na szczycie, to otrzymam niewłaściwą grupę 'foo'. – FooBar

Odpowiedz

0

Aby uzyskać xth obserwacje drugiego poziomu, jak chciał, można połączyć loc z iloc:

df.sort_index(level=[0, 1], ascending=[1, 0], inplace=True) 
df.loc[2015].iloc[:10] 

działa zgodnie z oczekiwaniami. To nie odpowiada na dziwne blokowanie indeksów w.r.t. lexsorting jednak.

0

Dla mnie to działało za pomocą sort_index(axis=1):

df = df.sort_index(axis=1) 

Gdy to zrobisz, możesz użyć slice lub pandas.IndexSlice, np:

df.loc[:, idx[:, 'A']] 
6

Po pierwsze należy nie sortowania tak:

df.sort_index(level=['year','foo'], ascending=[1, 0], inplace=True) 

Powinien naprawić KeyError. Ale df.loc[pd.IndexSlice[2002, :10], :] nie da ci oczekiwanego rezultatu. Funkcja loc nie jest iloc i spróbuje znaleźć w indeksach foo 0,1..9. Wtórne poziomy Multiindex nie obsługują iloc, sugerowałbym używanie groupby. Jeśli masz już ten multiindex należy zrobić:

df.reset_index() 
df = df.sort_values(by=['year','foo'],ascending=[True,False]) 
df.groupby('year').head(10) 

jeśli trzeba n wpisy z najmniejszą foo można użyć tail(n). Jeśli potrzebujesz, powiedzmy, pierwszej, trzeciej i piątej pozycji, możesz użyć nth([0,2,4]), o czym wspomniałeś w pytaniu. Myślę, że jest to najbardziej efektywny sposób, w jaki można to zrobić.

Powiązane problemy