使用条件累计量进行自定义聚合

时间:2019-10-04 11:52:14

标签: python pandas aggregation cumsum

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

enter image description here

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

换句话说,我想得到这样的东西

enter image description here

用户1首先执行action_A并得到10。然后,action_B给我们10 + 5 =15。Action_C代表金钱损失,给与使用15-5 =10。最后,action_D与C相同,我们得到10-15 = -5。

如何用熊猫来实现呢?我尝试使用

进行自定义聚合
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))

2 个答案:

答案 0 :(得分:3)

Series.isinSeries.mask创建并最后使用GroupBy.cumsum的掩码加上-1的多个值:

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())

答案 1 :(得分:1)

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

首先,我给表示费用的动作加负号。

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()