我有一个看起来像这样的数据框
取决于用户动作(可能有四种类型的动作),我想在给定的时间点累积用户的钱数。类型A和B的操作代表用户的收入,类型C和D的操作代表用户的费用。
换句话说,我想得到这样的东西
用户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))
答案 0 :(得分:3)
由Series.isin
和Series.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()