Вероятно, это решение принято для производительности.Вы можете прочитать об этом в Сортировка MultiIndex , что означает, что вы хотите, чтобы ваш индекс был отсортирован по лексической сортировке, что поддерживается текущим значением .loc
.Если бы он дал вам желаемый результат, индекс не был бы отсортирован по тексту, что может привести к нескольким проблемам.Вы должны использовать .reindex
, так как это приведет к лексоризации MultiIndex
.
Ваш оригинал DataFrame
лексориентирован:
df.index.is_lexsorted()
#True
нежелательный вывод, который вы получаете, поддерживает эту сортировку:
df.loc[idx[:, values], values].index.is_lexsorted()
#True
Если бы мы изменили порядок с помощью .loc
, мы потеряем эту сортировку и теперь будем страдать от проблем с производительностью в соответствии с документацией.
subset = df.loc[[(0, 'B'), (0, 'A')], ['B', 'A']]
# B A
#0 B 1.0 1.0
# A 1.0 1.0
subset.index.is_lexsorted()
#False
Несмотря на то, что переиндексация занимает больше времени, это приведет к индексу, отсортированному по лексису.
subset2 = df.reindex(index=values, level=1)
subset2.index.is_lexsorted()
#True
Существуют непредвиденные последствия, когда ваш MultiIndex
не отсортирован по тексту.Так что, хотя subset
кажется, что оно отсортировано и что разделение диапазонов должно быть возможным, вы не можете.После .reindex
нарезка является жизнеспособной, потому что она сортируется по лексису:
subset.loc[(0,'B'): (0, 'A')]
#UnsortedIndexError: 'Key length (2) was greater than MultiIndex lexsort depth (1)'
subset2.loc[(0,'B'): (0, 'A')]
# A B C
#0 B 1.0 1.0 1.0
# A 1.0 1.0 1.0