如何在计算值并放入不同列的同时对 DataFrame 进行分组?

How can I groupby a DataFrame at the same time I count the values and put in different columns?

我有一个如下所示的 DataFrame

Index  Category  Class
 0        1        A
 1        1        A
 2        1        B
 3        2        A
 4        3        B
 5        3        B

我想得到一个按类别分组的输出数据框,每个 class 都有一列,其中包含 class 在每个类别中出现的次数,比如下面那个

Index Category   A   B
 0      1        2   1
 1      2        1   0
 2      3        0   2

到目前为止,我已经尝试了groupbyagg方法的各种组合,但仍然无法得到我想要的。我也尝试过 df.pivot_table(index='Category', columns='Class', aggfunc='count'),但是 return 没有列的 DataFrame。在这种情况下有什么可行的想法吗?

为计数分配虚拟值:

out = df.assign(val=1).pivot_table('val', 'Category', 'Class',
                                   aggfunc='count', fill_value=0).reset_index()
print(out)

# Output
Class  Category  A  B
0             1  2  1
1             2  1  0
2             3  0  2
    import pandas as pd
df = pd.DataFrame({'Index':[0,1,2,3,4,5],
                   'Category': [1,1,1,2,3,3],
                   'Class':['A','A','B','A','B','B'],
              })
df = df.groupby(['Category', 'Class']).count()
df = df.pivot_table(index='Category', columns='Class')
print(df)

输出:

             Index     
Class        A    B
Category           
1          2.0  1.0
2          1.0  NaN
3          NaN  2.0

您可以使用 aggfunc="size" 来达到您想要的结果:

>>> df.pivot_table(index='Category', columns='Class', aggfunc='size', fill_value=0)

Class     A  B
Category
1         2  1
2         1  0
3         0  2

或者,您可以使用 .groupby(...).size() 获取计数,然后取消堆叠以重塑您的数据:

>>> df.groupby(["Category", "Class"]).size().unstack(fill_value=0)

Class     A  B
Category
1         2  1
2         1  0
3         0  2

使用crosstab:

pd.crosstab(df['Category'], df['Class']).reset_index()

输出:

Class  Category  A  B
0             1  2  1
1             2  1  0
2             3  0  2