Python:aggfunc=count unique distinct的透视表

Python:aggfunc=count unique distinct的透视表,python,pandas,pivot-table,Python,Pandas,Pivot Table,此代码: df2 = ( pd.DataFrame({ 'X' : ['X1', 'X1', 'X1', 'X1'], 'Y' : ['Y2', 'Y1', 'Y1', 'Y1'], 'Z' : ['Z3', 'Z1', 'Z1', 'Z2'] }) ) g = df2.groupby('X') pd.pivot_table(g, values='X', rows='Y', cols='Z', margins=False, ag

此代码:

df2 = (
    pd.DataFrame({
        'X' : ['X1', 'X1', 'X1', 'X1'], 
        'Y' : ['Y2', 'Y1', 'Y1', 'Y1'], 
        'Z' : ['Z3', 'Z1', 'Z1', 'Z2']
    })
)
g = df2.groupby('X')
pd.pivot_table(g, values='X', rows='Y', cols='Z', margins=False, aggfunc='count')
返回以下错误:

Traceback (most recent call last): ... 
AttributeError: 'Index' object has no attribute 'index'
如何获得一个透视表,该透视表包含一个DataFrame列对另两个列的唯一值计数?
计数唯一是否有
aggfunc
?我应该使用
np.bincount()

注意。我知道“系列”
值\u counts()
但是我需要一个数据透视表


编辑:输出应为:

Z   Z1  Z2  Z3
Y             
Y1   1   1 NaN
Y2 NaN NaN   1

你是说像这样的事吗

>>> df2.pivot_table(values='X', rows='Y', cols='Z', aggfunc=lambda x: len(x.unique())

Z   Z1  Z2  Z3
Y             
Y1   1   1 NaN
Y2 NaN NaN   1

请注意,使用
len
假定数据帧中没有
NA
s。您可以执行
x.value\u counts().count()
len(x.dropna().unique())
其他操作。

您可以为
x的每个不同值构建透视表。在这种情况下,

for xval, xgroup in g:
    ptable = pd.pivot_table(xgroup, rows='Y', cols='Z', 
        margins=False, aggfunc=numpy.size)
将为
X
的每个值构造一个透视表。您可能需要使用
xvalue
索引
ptable
。使用此代码,我得到(对于
X1


这是计算
中的条目的好方法。pivot\u表

>>> df2.pivot_table(values='X', index=['Y','Z'], columns='X', aggfunc='count')

        X1  X2
Y   Z       
Y1  Z1   1   1
    Z2   1  NaN
Y2  Z3   1  NaN

aggfunc=pd.Series.nunique
提供不同的计数。完整代码如下:

df2.pivot_table(values='X', rows='Y', cols='Z', aggfunc=pd.Series.nunique)

此解决方案归功于@hume(见接受答案下的注释)。在此处添加作为更好的可发现性的答案。

因为至少有0.16版的pandas,所以它不使用参数“rows”

从0.23开始,解决方案为:

df2.pivot_table(values='X', index='Y', columns='Z', aggfunc=pd.Series.nunique)
返回:

Z    Z1   Z2   Z3
Y                
Y1  1.0  1.0  NaN
Y2  NaN  NaN  1.0
Z   Z1  Z2  Z3
Y           
Y1  1.0 1.0 NaN
Y2  NaN NaN 1.0

由于没有一个答案是最新版本的熊猫,我正在为这个问题写另一个解决方案:

import pandas as pd

# Set example
df2 = (
    pd.DataFrame({
        'X' : ['X1', 'X1', 'X1', 'X1'], 
        'Y' : ['Y2', 'Y1', 'Y1', 'Y1'], 
        'Z' : ['Z3', 'Z1', 'Z1', 'Z2']
    })
)

# Pivot
pd.crosstab(index=df2['Y'], columns=df2['Z'], values=df2['X'], aggfunc=pd.Series.nunique)
返回:

Z    Z1   Z2   Z3
Y                
Y1  1.0  1.0  NaN
Y2  NaN  NaN  1.0
Z   Z1  Z2  Z3
Y           
Y1  1.0 1.0 NaN
Y2  NaN NaN 1.0

为了获得最佳性能,我建议执行
DataFrame.drop\u duplicates
跟进
aggfunc='count'

其他人认为
aggfunc=pd.Series.nunique将起作用是正确的。但是,如果
索引
组的数量很大(>1000),这可能会很慢

因此,而不是(引用@Javier)

我建议

df2.drop_duplicates(['X', 'Y', 'Z']).pivot_table('X', 'Y', 'Z', aggfunc='count')

这是因为它保证每个子组(每个组合的
('Y','Z')
)都有唯一的(非重复的)值
'X'
aggfunc=pd.Series.nunique
将只计算序列的唯一值-在本例中,计算列的唯一值。但这并不能完全反映为
aggfunc='count'


对于简单的计数,最好使用
aggfunc=pd.Series.count

谢谢。但是,我不是在计算X的每个不同值的出现次数,我是在计算X中Y和Z的不同值的数量。只是为了用一个新的解决方案来更新它,
aggfunc=pd.Series.nunique
将解决这个问题,而且应该更有效。@休谟您的评论应该是一个实际的答案,这样更容易找到,特别是考虑到熊猫自2012年以来有了实质性的变化。这些不再是
pivot\u表的参数?现在我看到
索引
。对于国家排名0的俄罗斯1 1德国1 2澳大利亚2 3韩国3 4德国2,您会怎么做?我提供了一些详细的示例和替代方法,这正是需要的,没有模糊的lambda。注意:熊猫不再接受行/列作为参数。计数将为我们提供唯一计数?
pd.Series.nunique
非常慢,除非必要,否则最好使用
aggfunc='count'