我有一个数据框,如:
df = pd.DataFrame([
{'id': 1, 'bonus': True, 'value': 10 },
{'id': 1, 'bonus': True, 'value': 15 },
{'id': 1, 'bonus': False, 'value': 5 },
{'id': 2, 'bonus': False, 'value': 20 },
{'id': 2, 'bonus': True, 'value': 10 },
])
我想为每个标识符添加额外的“bonus_value”,如果当前行不是奖励,则包含所有相关id奖励的总和。就像是:
{'id': 1, 'bonus': True, value: 10, bonus_value: 0 },
{'id': 1, 'bonus': True, value: 15, bonus_value: 0 },
{'id': 1, 'bonus': False, value: 5, bonus_value: 25 },
{'id': 2, 'bonus': False, value: 20, bonus_value: 10 },
{'id': 2, 'bonus': True, value: 10, bonus_value: 0 },
奖金不能附加奖金。我只是想得到bonus_value
财产中所有相关身份奖金的总和。
我试图将它们分组:
per_id_groups = df.groupby(["id", "bonus"]).sum().reset_index()
updated_df = df.merge(
per_id_groups,
on=["id", "bonus"],
suffixes=["", "_with_bonus"]
)
updated_df["bonus_value"] = updated_df["value_with_bonus"] - updated_df["value"]
但显然,它不起作用:
bonus id value value_with_bonus bonus_value
0 True 1 10 25 15
1 True 1 15 25 10
2 False 1 5 5 0
3 False 2 20 20 0
4 True 2 10 10 0
实际上,当它是奖金时,我不应该在bonus_value
专栏中有任何价值。而且,更烦人的是,我没有在bonus=False
行中的总和。
我找不到解决这个问题的方法。我想我应该错过这里的熊猫功能? :)
你可以做两个步骤
df['bonus_value']=df.id.map(df[df.bonus].groupby('id').value.sum())# map the sum value for each group
df.loc[df.bonus,'bonus_value']=0 #then assign 0 to bonus is True
df
Out[205]:
bonus id value bonus_value
0 True 1 10 0
1 True 1 15 0
2 False 1 5 25
3 False 2 20 10
4 True 2 10 0
可以使用df.bonus
和index matching
过滤
df = df.set_index('id')
df.loc[~df.bonus,'bonus_value'] = df.loc[df.bonus].groupby('id').value.sum()
df.reset_index().fillna(0)
id bonus value bonus_value
0 1 True 10 0.0
1 1 True 15 0.0
2 1 False 5 25.0
3 2 False 20 10.0
4 2 True 10 0.0
df.assign(
bonus_value=df[~df.bonus].id.map(df.groupby(['bonus', 'id']).value.sum().xs(True)))
bonus id value bonus_value
0 True 1 10 NaN
1 True 1 15 NaN
2 False 1 5 25.0
3 False 2 20 10.0
4 True 2 10 NaN
这是我的实验
d2 = df.groupby(['bonus', 'id']).value.sum().rename('bonus_value').reset_index()
d2.bonus_value *= d2.bonus
d2.bonus ^= True
df.merge(d2)
bonus id value bonus_value
0 True 1 10 0
1 True 1 15 0
2 False 1 5 25
3 False 2 20 10
4 True 2 10 0