加快熊猫迭代

时间:2020-09-25 14:08:42

标签: python-3.x pandas dataframe data-analysis

我有一个由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

2 个答案:

答案 0 :(得分:5)

使用whereNaN屏蔽“失败”行,同时保留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')

我完全不确定,但我认为这可能有效