如何根据两列的条件求和并使用Pandas以交叉表格式呈现?

How to sum based on the condition of two columns and presented in crosstab format using Pandas?

给定以下数据框:

Name    Activity    Hour    Month
A       TT          5       1
A       TT          2       1
A       UU          1       1
A       UU          1       2
A       UU          1       3
B       TT          40      3
C       UU          10      1
D       TT          2       2
D       TT          2       2
D       TT          2       2
D       TT          5       1

如果行具有与 NameActivity.

相同的值,则下一步是求和

例如,对于 Name: AActivity: TT 的情况,将给出 7

的总和

然后,我想以monthactivity分组的交叉表格式呈现,如下图

                Month
       1           2          3
    TT  UU      TT  UU      TT  UU
A   7   1       0   1       0   1
B   0   0       0   0       40  0
C   0   10      0   0       0   0
D   5   0       6   0       0   0

请问能不能直接用pandas交叉表实现?

p.s.,类似但不同的话题已单独讨论。如果此线程被认为是 OP

的副本,请告诉我

考虑以下 df:

In [93]: df
Out[93]: 
   Name Activity  Hour  Month
0     A       TT     5      1
1     A       TT     2      1
2     A       UU     1      1
3     A       UU     1      2
4     A       UU     1      3
5     B       TT    40      3
6     C       UU    10      1
7     D       TT     2      2
8     D       TT     2      2
9     D       TT     2      2
10    D       TT     5      1

解决方法:1如果想使用pd.crosstab,可以这样做:

In [92]: pd.crosstab(df.Name, columns=[df.Month, df.Activity], values=df.Hour, aggfunc='sum').fillna(0)
Out[92]: 
Month       1          2          3     
Activity   TT    UU   TT   UU    TT   UU
Name                                    
A         7.0   1.0  0.0  1.0   0.0  1.0
B         0.0   0.0  0.0  0.0  40.0  0.0
C         0.0  10.0  0.0  0.0   0.0  0.0
D         5.0   0.0  6.0  0.0   0.0  0.0

解法:2 您可以使用 df.pivot_table:

In [89]: df.pivot_table(index='Name', columns=['Month', 'Activity'], values='Hour', aggfunc='sum', fill_value=0)
Out[89]: 
Month     1      2      3   
Activity TT  UU TT UU  TT UU
Name                        
A         7   1  0  1   0  1
B         0   0  0  0  40  0
C         0  10  0  0   0  0
D         5   0  6  0   0  0

您也可以使用 groupby 作为您之前的问题

df_final = df.groupby(['Month','Activity','Name']).Hour.sum().unstack([0,1], fill_value=0)

Out[338]:
Month     1      2      3
Activity TT  UU TT UU  TT UU
Name
A         7   1  0  1   0  1
B         0   0  0  0  40  0
C         0  10  0  0   0  0
D         5   0  6  0   0  0