使用条件 cumsum 的自定义聚合

Custom aggregation with conditional cumsum

我有一个看起来像这样的数据框

取决于用户操作(可能有四种类型的操作)我想在给定时间点累积用户的金额。 A、B类动作代表用户收入,C、D类动作代表用户支出。

换句话说,我想要这样的结果

用户 1 首先执行 action_A 并得到 10 作为结果。然后action_B给我们10 + 5 = 15。Action_C代表金钱损失,给使用15 - 5 = 10。最后,action_D和C一样,我们得到10 - 15 = -5.

如何使用 pandas 实现此功能?我尝试使用

进行自定义聚合
expanding().apply(agg_func)

但没有得到满意的结果。

编辑:数据框创建代码

ids = [1,1,1,1,2,2]
dates = ['2019-03-07 13:54', '2019-03-07 16:07', '2019-03-10 19:20', '2019-03-10 19:20', '2016-03-07 14:47', '2016-03-09 11:07']
amounts = [10., 5., 5., 15., 2., 4.]
actions = ['action_A', 'action_B', 'action_C', 'action_D', 'action_A', 'action_B']
result = [10, 15, 10, -5, 2, 6]

pd.DataFrame({'user_id': ids, 'start_date': dates, 'amount': amounts, 'action': actions, 'result': result}, index=range(6))

嘿希望这会给你一个提示:

首先我给代表费用的行为打负号。

df.loc[df.action.isin(['action_C','action_D'])].amount = -1 * df.loc[df.action.isin(['action_C','action_D'])].amount

然后你像这样创建结果列

df['result'] = df.amount.cumsum()

-1Series.isin and Series.mask and last use GroupBy.cumsum 创建的掩码的多个值:

df['result'] = (df['amount'].mask(df['action'].isin(['action_C','action_D']),
                                  df['amount'] * -1)
                           .groupby(df['user'])
                           .cumsum())
print (df['result'])
0    10.0
1    15.0
2    10.0
3    -5.0
4     2.0
5     6.0
Name: result, dtype: float64

辅助列的类似解决方案:

df['result'] = (df.assign(tmp = df['amount'].mask(df['action'].isin(['action_C','action_D']),
                                 df['amount']*-1))
                  .groupby('user')['tmp']
                  .cumsum())