我有一个由3列组成的DataFrame:CustomerId,Amount和Status(成功或失败)。 DataFrame不会以任何方式排序。一个CustomerId可以在DataFrame中重复多次。
我想使用以下逻辑在此DataFrame中引入新列:
df [totalamount] =状态为成功的每个客户的金额总和。
我已经有一个运行中的代码,但是使用df.iterrows会花费太多时间。因此,请您提供其他方法,例如熊猫向量化或numpy向量化。
例如,我想从前三列创建“ totalamount”列:
CustomerID Amount Status totalamount
0 1 5 Success 105 # since both transatctions were successful
1 2 10 Failed 80 # since one transaction was successful
2 3 50 Success 50
3 1 100 Success 105
4 2 80 Success 80
5 4 60 Failed 0
答案 0 :(得分:5)
使用where
用NaN
屏蔽“失败”行,同时保留DataFrame的长度。然后groupby
客户ID和transform
“金额”列的总和将结果带回到每一行。
df['totalamount'] = (df.where(df['Status'].eq('Success'))
.groupby(df['CustomerID'])['Amount']
.transform('sum'))
CustomerID Amount Status totalamount
0 1 5 Success 105.0
1 2 10 Faled 80.0
2 3 50 Success 50.0
3 1 100 Success 105.0
4 2 80 Success 80.0
5 4 60 Failed 0.0
使用where
的原因(而不是对DataFrame进行子设置)是因为groupby + sum默认将整个NaN
组的总和设为0,因此我们不需要任何额外的处理例如,客户ID 4。
答案 1 :(得分:1)
df_new = df.groupby(['CustomerID', 'Status'], sort=False)['Amount'].sum().reset_index()
df_new = (df_new[df_new['Status'] == 'Success']
.drop(columns='Status')
.rename(columns={'Amount': 'totalamount'}))
df = pd.merge(df, df_new , on=['CustomerID'], how='left')
我完全不确定,但我认为这可能有效