Python新手求助:Pandas按User_ID分组求和遇重复ID时重置
嘿,我完全懂你的需求!你要的是对连续出现的同一个User_ID的clicks字段求和,而不是把所有相同User_ID的记录都汇总到一起——也就是说,当某个User_ID断开后再次出现在新行时,求和要重置,对吧?普通的groupby('User_ID')会把所有同ID的行归为一组,自然达不到你的要求,咱们来一步步解决这个问题。
核心思路:给连续的User_ID批次打标识
要实现“连续相同ID求和、断开后重置”,关键是先给每一段连续的相同User_ID生成一个唯一的分组标识,然后再按这个标识+User_ID来分组求和。
具体实现步骤
构造样例数据(模拟你的场景)
先拿一个和你需求匹配的样例DataFrame来演示:import pandas as pd data = { 'User_ID': [19, 19, 20, 20, 19, 19, 21], 'clicks': [2, 3, 1, 4, 5, 2, 6] } df = pd.DataFrame(data)这里User_ID 19先连续出现2次,然后被20打断,之后又连续出现2次,正好对应你说的“再次出现时求和重置”的场景。
生成连续分组标识
用ne()方法判断当前行的User_ID和上一行是否不同,再用cumsum()累加生成分组ID:# 当当前行User_ID和上一行不同时,返回True,累加后得到唯一的分组编号 df['group_id'] = df['User_ID'].ne(df['User_ID'].shift()).cumsum()这一步之后,DataFrame会新增一列
group_id,每一段连续的相同User_ID会被分配同一个group_id,断开后重新生成新的id。按分组标识+User_ID求和
现在就可以按User_ID和group_id分组,对clicks求和了:# 分组求和后重置索引,得到结构化的结果 result = df.groupby(['User_ID', 'group_id'])['clicks'].sum().reset_index() # 如果不需要保留group_id列,可以直接删掉 result = result.drop('group_id', axis=1) print(result)
输出结果
运行上面的代码后,你会得到符合预期的结果:
User_ID clicks 0 19 5 1 20 5 2 19 7 3 21 6
可以看到,User_ID 19的两次连续出现分别求和(2+3=5,5+2=7),完全符合你“再次出现时求和重置”的要求。
额外拓展:如果需要每行的累计值
如果你不是要每个连续组的总和,而是要在原DataFrame里显示每行的累计clicks(比如第一行19的累计是2,第二行是5,然后19再次出现时累计从5开始),可以这样做:
df['cumulative_clicks'] = df.groupby('group_id')['clicks'].cumsum() print(df)
输出会是:
User_ID clicks group_id cumulative_clicks 0 19 2 1 2 1 19 3 1 5 2 20 1 2 1 3 20 4 2 5 4 19 5 3 5 5 19 2 3 7 6 21 6 4 6
内容的提问来源于stack exchange,提问作者Liu

