Подтвердить что ты не робот

Сортировка Multi-Index для полной глубины (Pandas)

У меня есть dataframe, который Im загружает из csv файла, а затем устанавливает индекс нескольким его столбцам (обычно два или три) методом set_index. Идея состоит в том, чтобы затем получить доступ к частям блока данных, используя несколько комбинаций клавиш:

df.set_index(['fileName','phrase'])
df.ix['somePath','somePhrase']

Возможно, этот тип выбора с несколькими ключами возможен только в том случае, если Multi-Index файловой системы сортируется на достаточной глубине. В этом случае, поскольку im снабжает два ключа, операция .ix не будет терпеть неудачу, только если мультиинтерфейс dataframe будет отсортирован на глубину не менее 2.

по какой-то причине, когда Im устанавливает индекс, как показано, хотя для меня кажется, что оба слоя отсортированы, вызов команды df.index.lexsort_depth возвращает 1, и я получаю следующую ошибку при попытке доступа двумя ключами: MultiIndex lexsort depth 1, key was length 2

Любая помощь?

4b9b3361

Ответ 1

Не совсем понятно, что вы просите. Многоиндексные документы здесь

OP должен установить индекс, затем сортировать на месте

df.set_index(['fileName','phrase'],inplace=True)
df.sortlevel(inplace=True)

Затем получить доступ к этим уровням через кортеж, чтобы получить конкретный результат

df.ix[('somePath','somePhrase')]

Возможно, просто дайте подобный игрушечный пример и покажите, что я хочу получить конкретный результат.

In [1]: arrays = [np.array(['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'])
   ...:    .....: ,
   ...:    .....:           np.array(['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two'])
   ...:    .....:           ]

In [2]: df = DataFrame(randn(8, 4), index=arrays)

In [3]: df
Out[3]: 
                0         1         2         3
bar one  1.654436  0.184326 -2.337694  0.625120
    two  0.308995  1.219156 -0.906315  1.555925
baz one -0.180826 -1.951569  1.617950 -1.401658
    two  0.399151 -1.305852  1.530370 -0.132802
foo one  1.097562  0.097126  0.387418  0.106769
    two  0.465681  0.270120 -0.387639 -0.142705
qux one -0.656487 -0.154881  0.495044 -1.380583
    two  0.274045 -0.070566  1.274355  1.172247

In [4]: df.index.lexsort_depth
Out[4]: 2

In [5]: df.ix[('foo','one')]
Out[5]: 
0    1.097562
1    0.097126
2    0.387418
3    0.106769
Name: (foo, one), dtype: float64

In [6]: df.ix['foo']
Out[6]: 
            0         1         2         3
one  1.097562  0.097126  0.387418  0.106769
two  0.465681  0.270120 -0.387639 -0.142705

In [7]: df.ix[['foo']]
Out[7]: 
                0         1         2         3
foo one  1.097562  0.097126  0.387418  0.106769
    two  0.465681  0.270120 -0.387639 -0.142705

In [8]: df.sortlevel(level=1)
Out[8]: 
                0         1         2         3
bar one  1.654436  0.184326 -2.337694  0.625120
baz one -0.180826 -1.951569  1.617950 -1.401658
foo one  1.097562  0.097126  0.387418  0.106769
qux one -0.656487 -0.154881  0.495044 -1.380583
bar two  0.308995  1.219156 -0.906315  1.555925
baz two  0.399151 -1.305852  1.530370 -0.132802
foo two  0.465681  0.270120 -0.387639 -0.142705
qux two  0.274045 -0.070566  1.274355  1.172247

In [10]: df.sortlevel(level=1).index.lexsort_depth
Out[10]: 0

Ответ 2

Я понимаю, что прошло какое-то время, но у меня, похоже, была такая же проблема, как у @idoda, при этом принятый ответ не работал с файловыми кадрами MultiIndex, когда числовые кадры могут иметь несколько индексов как по столбцам, так и по индексу. Трюк, который в настоящее время не показан здесь, заключается в том, что существует опция "ось", которая по умолчанию равна нулю, но также может быть установлена ​​в 1.

Например, если вы попытаетесь:

df.sortlevel(inplace=True,sort_remaining=True)

И все еще возникают ошибки lexsort, возможно, важно знать, что они являются по умолчанию "ось = 0" kwarg. Таким образом, вы также можете попробовать добавить

df.sortlevel(axis=1,inplace=True,sort_remaining=True)

Который должен сортировать другое направление. Если вы не хотите думать об этом, вы можете просто перетащить его с помощью:

df.sortlevel(axis=0,inplace=True,sort_remaining=True)
df.sortlevel(axis=1,inplace=True,sort_remaining=True)

Это должно полностью сортировать как столбцы, так и индексы строк на всех уровнях. У меня была такая же проблема, и я не мог получить полный lexsort с предложенным ответом, но небольшое исследование показало, что даже при "sort_remaining" True sortlevel применяется только к одной оси. Эти фрагменты являются решением того, что, по-видимому, является текущим питонским нативным ответом. Надеюсь, кто-то посчитает это полезным!