ValueError при попытке иметь мультииндекс в DataFrame.pivot - PullRequest
0 голосов
/ 29 августа 2018

Я прочитал Панд: как запустить сводную таблицу с мультииндексом? , но это не могло решить мою проблему.

Учитывая приведенный ниже кадр данных:

import pandas as pd
df = pd.DataFrame({
    "date": ["20180920"] * 6,
    "id": ["A123456789"] * 6,
    "test": ["a", "b", "c", "d", "e", "f"],
    "result": [70, 90, 110, "(-)", "(+)", 0.3],
    "ref": ["< 90", "70 - 100", "100 - 120", "(-)", "(-)", "< 1"]
})

Я хотел бы расширить столбец test, использовать значения в result и игнорировать ref. Другими словами, желаемый вывод выглядит так:

       date          id      a   b    c    d    e    f
0  20180920  A123456789     70  90  110  (-)  (+)  0.3

Итак, я попытался df.pivot(index=["date", "id"], columns="test", values="result"), но это не удалось с ValueError: Длина переданных значений равна 6, индекс подразумевает 2 . Я думаю, что это связано с «Если массив передан, он должен быть той же длины, что и данные». в pivot_table документации , но я просто не понимаю, что это значит. Может кто-нибудь уточнить, пожалуйста?

Кстати, я наконец-то получил желаемый результат на df.drop(columns="ref").set_index(["date", "id", "test"]).unstack(level=2). Это единственный правильный путь?

Ответы [ 2 ]

0 голосов
/ 29 августа 2018

pivot возможно использовать, но код немного сумасшедший:

df = (df.set_index(["date", "id"])
        .pivot(columns="test")['result']
        .reset_index()
        .rename_axis(None, axis=1)
     )
print (df)

       date          id   a   b    c    d    e    f
0  20180920  A123456789  70  90  110  (-)  (+)  0.3

О документах вы можете проверить выпуск 16578 , а в пандах 0.24.0 должно быть улучшенные документы или, возможно, новая поддержка для работы с MultiIndex? Немного неясно также из номера 8160 .

На мой взгляд, ваш последний код должен быть лишь немного улучшен (то же решение, что и @Vaishali) - создайте Series with MultiIndex, выбрав после set_index, а для unstack удалите level, потому что по умолчанию последний уровень не накладывается MultiIndex - Series.unstack:

level : int, строка или список из них, последний уровень по умолчанию

Уровень (уровни) для снятия стека, может пройти имя уровня

#all 3 return same output
df.set_index(["date", "id", "test"])['result'].unstack()
df.set_index(["date", "id", "test"])['result'].unstack(level=2)
df.set_index(["date", "id", "test"])['result'].unstack(level=-1)
0 голосов
/ 29 августа 2018

pivot не принимает список столбцов в качестве индекса, поэтому вам нужно использовать pivot_table. Здесь сначала используется агрегация с предположением, что дубликатов нет.

pd.pivot_table(df,index=["date", "id"], columns="test", values="result", aggfunc= 'first')\
.reset_index().rename_axis(None, 1)

Было бы безопаснее использовать set_index, unstack и rename_axis, как предложено @piRsquared,

df.set_index(['date', 'id', 'test']).result.unstack()\
.reset_index().rename_axis(None, 1)

В любом случае, вы получите,

    date    id          a   b   c   d   e   f
20180920    A123456789  70  90  110 (-) (+) 0.3
...