问题描述
我有这个数据框
lst = [['AA','Z',10,1,0],['BB','Y',['AA',20,2,['CC','X',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_name
和last_name
,而不是在其中添加{{ 1}},否则请保持原样。
我在做
val
此后,我可以更改df1.groupby(['first_name','department']).sum().groupby(level=0).cumsum()
列,并将这些行附加到原始数据帧中。但这不是必需的输出。
解决方法
这是使用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