Python pandas-具有非数值的pivot_表?(DataError:没有要聚合的数字类型)

Python pandas-具有非数值的pivot_表?(DataError:没有要聚合的数字类型),python,pandas,pivot-table,dataframe,Python,Pandas,Pivot Table,Dataframe,我正在尝试对包含字符串作为结果的表进行透视 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

我正在尝试对包含字符串作为结果的表进行透视

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:没有要聚合的数值类型

当我将结果值更改为数字时,这将按预期工作:

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

我知道我可以将字符串映射为数值,然后反转操作,但也许有一个更优雅的解决方案?

我认为最好的折衷办法是用真/假替换开/关,这将使熊猫更好地“理解”数据,并以智能、预期的方式行事

df2 = df1.replace({'on': True, 'off': False})
你在问题中基本上承认了这一点。我的回答是,我不认为有更好的方法,不管接下来发生什么,你都应该替换“开”/“关”


正如Andy Hayden在评论中指出的那样,如果用1/0替换开/关,您将获得更好的性能。

我最初的回答基于Pandas 0.14.1,从那以后,pivot_表函数中的许多内容都发生了变化(行-->索引,列-->列…)

此外,我发布的原始lambda技巧似乎不再适用于熊猫0.18。您必须提供一个缩减函数(即使是最小值、最大值或平均值)。但即使这样似乎也不合适——因为我们不是在减少数据集,而是在转换它。。。。所以我更努力地看着unstack

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']
首先,使用index+要堆叠的列对数据设置索引,然后使用level arg调用unstack

df1.set_index(['index'] + unstack_cols).unstack(level=unstack_cols)
生成的数据帧如下所示


+1,但是使用1和0可能更好,因为DataFrame具有float而不是object dtype:)最后一个替换pivot()的解决方案在0.17中进行了更改。1@RandallGoodwin,我意识到这个问题已经两年了,但我用lambda得到了错误“ValueError:Function not reduce”,你会知道为什么吗?另一个想法是:如果你可能会出现多个值,你可以通过让你的
aggfunc=lambda x::.join([str(y)代表y in x])
@dllahr使用相同的想法来压缩字符串,但你也可以使用各种字符串访问器。e、 g.
aggfunc=lambda x:x.str.cat()
FWIW,我在这里用了一个答案:@RustyShackleford请看我或dllahr的评论