2016-10-05 9 views
8

У меня есть фрейм данных с индексом (year, foo), где я хотел бы, чтобы выбрать X крупнейшие наблюдения foo где year == someYear.мультииндексная нарезка требует индекса быть полностью lexsorted

Мой подход был

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

, но я получаю

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

Я пробовал различные варианты сортировки (например, ascending = [0, 0]), но все они в результате какой-то ошибки.

Если мне нужен только номер xth, я мог бы df.groupby(level=[0]).nth(x) после сортировки, но так как я хочу набор строк, это не очень эффективно.

Каков наилучший способ выбора этих строк? Некоторые данные, чтобы играть с:

    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

Что происходит, если вы просто сортируете с помощью 'df.sort_index (inplace = True)'? – ASGM

+0

@ASGM Это работает, но поскольку я не восхожу на то, я получу неправильную группу 'foo'. – FooBar

ответ

0

Чтобы получить xth наблюдения второго уровня, как хотелось, можно объединить loc с iloc:

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

работает, как ожидалось. Это не отвечает на странную блокировку индекса w.r.t. lexsorting, однако.

0

Для меня он работал с помощью sort_index(axis=1):

df = df.sort_index(axis=1) 

После того, как вы сделаете это, вы можете использовать slice или pandas.IndexSlice, например:

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

Во-первых, вы должны сделать сортировку так:

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

Он должен исправить KeyError. Но df.loc[pd.IndexSlice[2002, :10], :] не даст вам результата, которого вы ожидаете. Функция loc не является iloc, и она попытается найти в foo индексы 0,1..9. Вторичные уровни Multiindex не поддерживают iloc, я бы предложил использовать groupby. Если у вас уже есть этот мультииндексных вы должны сделать:

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

Если вам нужно п записей с наименьшим обув вы можете использовать tail(n). Если вам нужны, скажем, первая, третья и пятая записи, вы можете использовать nth([0,2,4]), как вы упомянули в вопросе. Я думаю, что это самый эффективный способ сделать это.

Смежные вопросы