You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Pandas中实现仅对非当前ID的历史值累加求和

问题描述

给定如下DataFrame:

import pandas as pd
df = pd.DataFrame({'ID': ['a','b','a','c','b','a','c','b','a','c'], 'Value': [3, 2, 3, 1, 5, 3, 4, 2, 6, 1]})

需要计算Value列的累加和,但仅累加当前行之前所有ID不等于当前ID的Value值。预期结果如下:

df_result = pd.DataFrame({'ID': ['a','b','a','c','b','a','c','b','a','c'], 
                          'Value': [3, 2, 3, 1, 5, 3, 4, 2, 6, 1],
                          'Sum':[0,3,2,8,7,8,16,14,14,24]})

尝试过np.where和groupby但未得到预期效果,这类动态对比当前ID与之前行ID的累加场景,和常规的固定条件累加不同。

解决方案

可以通过全局累计和减去当前ID的累计和的思路实现,避免逐行循环,效率更优:

  1. 计算全局的累计和(到当前行的前一行):用cumsum()后偏移一位,第一行补0。
  2. 计算每个ID的累计和(到当前行的前一行):用groupby('ID')['Value'].cumsum()后偏移一位,第一行补0。
  3. 两者相减就是当前行之前所有非当前ID的Value累加和。

具体代码:

import pandas as pd

df = pd.DataFrame({'ID': ['a','b','a','c','b','a','c','b','a','c'], 'Value': [3, 2, 3, 1, 5, 3, 4, 2, 6, 1]})

# 全局累计和,取前一行的总和
global_cumsum = df['Value'].cumsum().shift(fill_value=0)
# 各ID的累计和,取前一行同ID的总和
id_cumsum = df.groupby('ID')['Value'].cumsum().shift(fill_value=0)
# 计算目标Sum列
df['Sum'] = global_cumsum - id_cumsum

print(df)

运行结果与预期一致:

ID  Value  Sum
0  a      3    0
1  b      2    3
2  a      3    2
3  c      1    8
4  b      5    7
5  a      3    8
6  c      4   16
7  b      2   14
8  a      6   14
9  c      1   24

思路说明

  • global_cumsum:第n行的值是前n-1行所有Value的总和,比如第1行的global_cumsum是第0行的3,第2行是前两行的3+2=5。
  • id_cumsum:第n行的值是前n-1行中与当前行ID相同的Value总和,比如第2行ID为a,id_cumsum是第0行的3;第4行ID为b,id_cumsum是第1行的2。
  • 两者相减后,正好得到前n-1行中非当前ID的Value总和,完全匹配需求。

内容的提问来源于stack exchange,提问作者Syhaa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 21:15:42