此代码:
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
你的意思是这样的吗?
>>> 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())
。
这是计算
.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
从 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
aggfunc=pd.Series.nunique
提供不同计数。完整代码如下:
df2.pivot_table(values='X', rows='Y', cols='Z', aggfunc=pd.Series.nunique)
此解决方案归功于@hume(请参阅已接受答案下的评论)。在此处添加作为答案以获得更好的可发现性。
aggfunc
中的
pandas.DataFrame.pivot_table
参数会将'nunique'
视为string
,或在list
中
pandas 1.5.0
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
您可以为
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
aggfunc=pd.Series.nunique
将仅计算系列的唯一值 - 在本例中计算列的唯一值。但这并不能完全反映出作为 aggfunc='count'
的替代方案
为了简单计数,最好使用
aggfunc=pd.Series.count
由于没有一个答案是最新版本的 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
为了获得最佳性能,我建议执行
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'
值。
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”。