панды - сводная таблица с числовыми значениями? (DataError: нет числовых типов для агрегирования)

Я пытаюсь сделать поворот таблицы, содержащей строки в качестве результатов.

import pandas as pd

df1 = pd.DataFrame({'index' : range(8),
'variable1' : ["A","A","B","B","A","B","B","A"],
'variable2' : ["a","b","a","b","a","b","a","b"],
'variable3' : ["x","x","x","y","y","y","x","y"],
'result': ["on","off","off","on","on","off","off","on"]})

df1.pivot_table(values='result',rows='index',cols=['variable1','variable2','variable3'])

А я: DataError: No numeric types to aggregate.

это работает по назначению, Когда я изменяю значения результата на числа:

df2 = pd.DataFrame({'index' : range(8),
'variable1' : ["A","A","B","B","A","B","B","A"],
'variable2' : ["a","b","a","b","a","b","a","b"],
'variable3' : ["x","x","x","y","y","y","x","y"],
'result': [1,0,0,1,1,0,0,1]})

df2.pivot_table(values='result',rows='index',cols=['variable1','variable2','variable3'])

и я получаю то, что мне нужно:

variable1   A               B    
variable2   a       b       a   b
variable3   x   y   x   y   x   y
index                            
0           1 NaN NaN NaN NaN NaN
1         NaN NaN   0 NaN NaN NaN
2         NaN NaN NaN NaN   0 NaN
3         NaN NaN NaN NaN NaN   1
4         NaN   1 NaN NaN NaN NaN
5         NaN NaN NaN NaN NaN   0
6         NaN NaN NaN NaN   0 NaN
7         NaN NaN NaN   1 NaN NaN

Я знаю, что могу сопоставить строки с числовыми значениями, А затем отменить операцию, но, может быть, есть более элегантное решение?

2 ответов


мой первоначальный ответ был основан на панды 0.14.1, и с тех пор, многое изменилось в функции сводная_таблица (строки -- индекс>, седла --> столбцы... )

кроме того, похоже, что оригинальный лямбда-трюк, который я опубликовал, больше не работает на панд 0.18. Вы должны предоставить функцию уменьшения (даже если это min, max или mean). Но даже это казалось неправильным-потому что мы не сокращаем набор данных, а просто преобразуем его.... Поэтому я пристальнее вгляделся в анстака...

import pandas as pd

df1 = pd.DataFrame({'index' : range(8),
'variable1' : ["A","A","B","B","A","B","B","A"],
'variable2' : ["a","b","a","b","a","b","a","b"],
'variable3' : ["x","x","x","y","y","y","x","y"],
'result': ["on","off","off","on","on","off","off","on"]})

# these are the columns to end up in the multi-index columns.
unstack_cols = ['variable1', 'variable2', 'variable3']

Сначала установите индекс на данные, используя индекс + столбцы, которые вы хотите сложить, затем вызовите unstack с помощью уровня arg.

df1.set_index(['index'] + unstack_cols).unstack(level=unstack_cols)

результирующий фрейм данных ниже.

enter image description here


Я думаю, что лучший компромисс-заменить on/off на True / False, что позволит панд лучше "понимать" данные и действовать разумно, ожидаемым образом.

df2 = df1.replace({'on': True, 'off': False})

вы по существу признал это в своем вопросе. Мой ответ: я не думаю, что есть лучший способ, и вы должны заменить " on " / " off " в любом случае для того, что будет дальше.

Как указывает Энди Хейден в комментариях, вы получите лучшую производительность, если замените on / off на 1/0.