计算所有部门列的累积总和

时间:2020-08-12 19:24:35

标签: python python-3.x pandas pandas-groupby

我有这个数据框

lst = [['AA','Z',10,1,0],['BB','Y',10,1,0],
       ['AA','Z',20,2,0],['CC','X',10,2,0]]
df1 = pd.DataFrame(lst,columns = ['first_name','last_name','val','department','is_cum'])

看起来像这样

  first_name last_name  val  department  is_cum
0         AA         Z   10           1      NO
1         BB         Y   10           1      NO
2         AA         Z   20           2      NO
3         CC         X   10           2      NO

我想要输出类似这样的东西

  first_name last_name  val  department  is_cum
0         AA         Z   10           1      NO
1         BB         Y   10           1      NO
2         AA         Z   10           1     YES
3         BB         Y   10           1     YES

4         AA         Z   20           2      NO
5         CC         X   10           2      NO
6         AA         Z   30         1,2     YES
7         CC         X   10           2     YES
8         BB         Y   10           1     YES

所有is_cum否的行都与输入数据帧相同,新填充的行是is_cum为YES的累积行。

第2行和第3行与0和1相同,因为我们只有一个department进行累加。第6,7,8行是department 1和department 2的累加。如果我们在部门1和部门2中拥有相同的first_namelast_name,而不是在其中添加{{ 1}},否则请保持原样。

我在做

val

此后,我可以更改df1.groupby(['first_name','last_name','department']).sum().groupby(level=0).cumsum() 列,并将这些行附加到原始数据帧中。但这不是必需的输出。

1 个答案:

答案 0 :(得分:2)

这是使用pivot_table来沿列进行累加的一种方法。其余的几乎都达到了预期的输出。

df_ = (df1.assign(dpt=df1['department'], 
                  department=df1['department'].astype(str))\
          .pivot_table(index=['first_name','last_name'], columns='dpt', 
                       values=['val', 'department'], 
                       aggfunc={'val':sum,'department':lambda x: list(x)})
          .assign(val=lambda x: x['val'].cumsum(axis=1).ffill(axis=1), 
                  department=lambda x: x['department'].apply(lambda x: x.dropna().cumsum(), axis=1)
                                                        .ffill(axis=1))
                 )

res= (pd.concat([df1.assign(is_cum='NO', dpt=df1['department']), 
                 df_.stack().reset_index()
                    .assign(is_cum='YES',
                            department=lambda x: x['department'].apply(','.join))])
        .sort_values(['dpt', 'is_cum']).drop('dpt',axis=1)
        .reset_index(drop=True)
     )

你会得到

print(res)
  first_name last_name   val department is_cum
0         AA         Z  10.0          1     NO
1         BB         Y  10.0          1     NO
2         AA         Z  10.0          1    YES
3         BB         Y  10.0          1    YES
4         AA         Z  20.0          2     NO
5         CC         X  10.0          2     NO
6         AA         Z  30.0        1,2    YES
7         BB         Y  10.0          1    YES
8         CC         X  10.0          2    YES