如何使用pandas数据透视表聚合唯一计数

问题描述 投票:0回答:10

此代码:

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()
吗?

注意。我知道

pandas.Series.values_counts()
但我需要一个数据透视表。


编辑:输出应该是:

Z   Z1  Z2  Z3
Y             
Y1   1   1 NaN
Y2 NaN NaN   1
python pandas pivot-table
10个回答
137
投票

你的意思是这样的吗?

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

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

请注意,使用

len
假设您的 DataFrame 中没有
NA
。否则,您可以执行
x.value_counts().count()
len(x.dropna().unique())


64
投票

这是计算

.pivot_table
中的条目数的好方法:

>>> 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

46
投票

从 pandas 0.16 版本开始,它不接受参数“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

13
投票

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

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

此解决方案归功于@hume(请参阅已接受答案下的评论)。在此处添加作为答案以获得更好的可发现性。


6
投票
out = df2.pivot_table(values='X', index='Y', columns='Z', aggfunc=['nunique', 'count', lambda x: len(x.unique()), len])

[out]:
             nunique           count           <lambda>            len          
Z       Z1   Z2   Z3    Z1   Z2   Z3       Z1   Z2   Z3   Z1   Z2   Z3
Y                                                                     
Y1     1.0  1.0  NaN   2.0  1.0  NaN      1.0  1.0  NaN  2.0  1.0  NaN
Y2     NaN  NaN  1.0   NaN  NaN  1.0      NaN  NaN  1.0  NaN  NaN  1.0


out = df2.pivot_table(values='X', index='Y', columns='Z', aggfunc='nunique')

[out]:
Z    Z1   Z2   Z3
Y                
Y1  1.0  1.0  NaN
Y2  NaN  NaN  1.0

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

[out]:
             nunique          
Z       Z1   Z2   Z3
Y                   
Y1     1.0  1.0  NaN
Y2     NaN  NaN  1.0

4
投票

您可以为

X
的每个不同值构建一个数据透视表。在这种情况下,

for xval, xgroup in g:
    ptable = pd.pivot_table(xgroup, rows='Y', cols='Z', 
        margins=False, aggfunc=numpy.size)

将为

X
的每个值构建一个数据透视表。您可能需要使用
ptable
来索引
xvalue
。通过这段代码,我得到(
X1

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

1
投票

aggfunc=pd.Series.nunique
将仅计算系列的唯一值 - 在本例中计算列的唯一值。但这并不能完全反映出作为
aggfunc='count'

的替代方案

为了简单计数,最好使用

aggfunc=pd.Series.count


1
投票

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

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

0
投票

为了获得最佳性能,我建议执行

DataFrame.drop_duplicates
跟进
aggfunc='count'

其他人是正确的,

aggfunc=pd.Series.nunique
会起作用。但是,如果您拥有的
index
组数量很大(>1000),这可能会很慢。

所以而不是(引用@Javier)

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

我建议

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

这是有效的,因为它保证每个子组(

('Y', 'Z')
的每个组合)都将具有唯一(非重复)的
'X'
值。


0
投票
res = df2.pivot_table(index = 'Y', columns = 'Z', values = 'X', aggfunc = "nunique")
print(res)

输出为:

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

这个答案与@Javier 的几乎相同。唯一的区别是 aggfunc 使用字符串名称“nunique”。

© www.soinside.com 2019 - 2024. All rights reserved.