Pandas实现按用户分组筛选code='P'并求和,且将结果填充至所有行
Pandas实现按用户分组筛选code='P'并求和,且将结果填充至所有行
嘿,这个需求我之前处理数据的时候也碰到过!你之前的写法问题出在先筛选了code='P'的行再分组,所以结果只在P的行有值,其他行都是NaN。其实只要调整一下逻辑顺序,就能把求和结果填充到每个用户的所有行啦,给你几个实用的方法:
方法一:用groupby + transform直接实现(最简洁)
这个方法利用transform会把分组计算的结果自动广播到组内每一行的特性,在transform的lambda里针对每个用户组,只计算code='P'的value之和:
import pandas as pd # 假设你的原始数据是这个df df = pd.DataFrame({ 'user': ['0001', '0001', '0001', '0002', '0002', '0003'], 'code': ['P', 'P', 'N', 'N', 'N', 'P'], 'value': [10, 20, 10, 40, 30, 10] }) # 核心代码 df['Sum_of_P'] = df.groupby('user').apply( lambda group: group['value'][group['code'] == 'P'].sum() ).reindex(df['user']).values
方法二:先预计算每个用户的P总和,再映射到原表(高效推荐)
如果你的数据量很大,用apply可能有点慢,那可以先提前算出每个用户的P的总和(没有的用户直接填0),再通过map把值对应到每一行:
# 先计算每个用户的code='P'的value总和 user_p_total = df[df['code'] == 'P'].groupby('user')['value'].sum() # 把所有用户都包含进来,没有P的用户总和设为0 user_p_total = user_p_total.reindex(df['user'].unique(), fill_value=0) # 映射到原DataFrame的每一行 df['Sum_of_P'] = df['user'].map(user_p_total)
方法三:用transform结合条件判断(更直观)
还有一种更直白的写法,在transform里用条件判断标记出P的行,再求和:
import numpy as np df['Sum_of_P'] = df.groupby('user')['value'].transform( lambda x: np.sum(np.where(df.loc[x.index, 'code'] == 'P', x, 0)) )
运行以上任意一种方法,你都会得到想要的结果:每个用户的所有行都会填充该用户code='P'的value总和,没有P的用户就填0,完全符合你给出的输出示例~
备注:内容来源于stack exchange,提问作者Bijan
相关产品推荐
相关产品推荐

