MultiIndex Slicing требует, чтобы индекс был полностью lexsorted

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

Мой подход

 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 

4 Solutions collect form web for “MultiIndex Slicing требует, чтобы индекс был полностью lexsorted”

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

 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) 

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

ascending должен быть логическим, а не списком . Попробуйте сортировку следующим образом:

df.sort_index(ascending=True, inplace=True)

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

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

работает, как ожидалось. Тем не менее, это не отвечает на странную блокировку индекса по сравнению с lexsorting.

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

 df = df.sort_index(axis=1) 

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

 df.loc[:, idx[:, 'A']] 
  • Панды: медленное преобразование даты
  • как получить несколько условных операций после группы Pandas?
  • Pandas dropna - магазин упал рядами
  • как преобразовать несколько слоев вложенной json в таблицу sql
  • Ошибка ремаркетинга Pandas: действует только с DatetimeIndex или PeriodIndex
  • Почему панды применяются гораздо медленнее, чем слияние данных
  • Выбор столбцов Pandas по dtype
  • Смешанные типы при чтении файлов csv. Причины, исправления и последствия
  • Лучший способ загрузить данные MongoDB в DataFrame с помощью Pandas и PyMongo?
  • Панды: самый быстрый способ разрешить IP-адрес страны
  • Получить количество значений по столбцам - Pandas DataFrame
  • Python - лучший язык программирования в мире.