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

如何在Pandas中按组累加(cumsum)并在累加值为负时重置为0?

Pandas分组后实现累加负值重置为0的cumsum操作

需求:在Pandas中对分组后的数据集执行累加(cumsum)操作,要求累加结果为负值时重置为0,生成expected_output列。

示例数据与初始尝试

先构造示例数据集,并尝试普通分组累加:

import pandas as pd

groupa = ['A', 'A', 'A', 'A', 'A', 'A', 'A', 'B', 'B', 'B', 'C', 'C', 'C', 'C']
valuesa = [-5, 4, 3, -4, -2, -2, 2, -2, 5, -2, 3, 6, 7, -11]
expected_output = [0, 4, 7, 3, 1, 0, 2, 0, 5, 3, 3, 9, 16, 5]

dfa = pd.DataFrame(list(zip(groupa, valuesa)), columns=['group', 'val'])
dfa['expected_output'] = pd.Series(expected_output)
# 普通分组累加,结果会出现负值,不符合需求
dfa['cumsum_output'] = dfa.groupby('group')['val'].cumsum()

正确实现代码

通过分组区间划分+截断负值的方式实现需求:

# 标记所有值为负的行
nega = dfa['val'] < 0
# 按反向负值累计分组+原数据分组,执行累加后将负值截断为0
dfa['output'] = dfa['val'].groupby(
    [nega[::-1].cumsum(), dfa['group']]).cumsum().clip(0)

最终结果

group   val  expected_output  cumsum_output  output
0       A    -5                0             -5       0
1       A     4                4             -1       4
2       A     3                7              2       7
3       A    -4                3             -2       3
4       A    -2                1             -4       0
5       A    -2                0             -6       0
6       A     2                2             -4       2
7       B    -2                0             -2       0
8       B     5                5              3       5
9       B    -2                3              1       3
10      C     3                3              3       3
11      C     6                9              9       9
12      C     7               16             16      16
13      C   -11                5              5       5

逻辑说明

  • nega = dfa['val'] < 0:标记每个值是否为负,作为划分累加重置区间的依据
  • nega[::-1].cumsum():反向累计负值标记,每次出现负值时生成新的分组键,触发累加重置
  • 结合原group分组,确保每个分组内独立处理累加逻辑
  • .clip(0):将累加结果中的负值直接截断为0,满足需求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 11:11:15