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

Pandas:按id和consecBool分组时,遇False重置累加计数器

问题:布尔列值为False时重置分组累加计数器

之前参考的「累计统计True值」方案无法满足需求——该方案默认数据集无独立分组,但实际需要按id和连续的consecBool块进行分组,要求每次consecBool为False时,后续的累加计数器重置。

示例数据与当前错误实现

先看示例数据集和当前错误的代码:

import pandas as pd

df = pd.DataFrame({'id': [1, 1, 1, 1, 1, 1, 1],
              'consecDays': [0, 1, 1, 1, 0, 1, 1],
              'consecBool': [False, True, True, True, False, True, True],
              'expected': [0, 1, 2, 3, 0, 1, 2]})

# 当前错误的累加方式
df['Counter'] = df.groupby(['id', 'consecBool'])['consecDays'].cumsum()

执行后得到的Counter列不符合预期,错误结果如下:

id  consecDays  consecBool  expected  Counter
0   1           0       False         0        0
1   1           1        True         1        1
2   1           1        True         2        2
3   1           1        True         3        3
4   1           0       False         0        0
5   1           1        True         1        4
6   1           1        True         2        5

可以看到,第5、6行的Counter没有重置,而是继续累加之前True块的数值,这和expected列的要求不符。

正确解决方案

核心思路是:为每个连续的consecBool=True块生成独立的子分组标识,结合id进行累加,最后将consecBool=False的行计数器设为0。

代码实现

# 1. 按id分组,生成连续布尔块的分组标识:每次布尔值切换时,分组ID递增
df['group_id'] = df.groupby('id')['consecBool'].transform(
    lambda x: x.ne(x.shift()).cumsum()
)

# 2. 按id和group_id分组累加consecDays
df['Counter'] = df.groupby(['id', 'group_id'])['consecDays'].cumsum()

# 3. 将consecBool为False的行Counter设为0
df.loc[~df['consecBool'], 'Counter'] = 0

正确结果

执行后得到符合预期的结果:

id  consecDays  consecBool  expected  group_id  Counter
0   1           0       False         0         1        0
1   1           1        True         1         2        1
2   1           1        True         2         2        2
3   1           1        True         3         2        3
4   1           0       False         0         3        0
5   1           1        True         1         4        1
6   1           1        True         2         4        2

逻辑说明

  • group_id的生成:通过x.ne(x.shift())检测当前行和前一行的consecBool是否不同,不同则标记为True,再用cumsum()累加生成唯一的分组ID,这样每个连续的True块会被分到独立的分组中。
  • 分组累加时,每个独立的True块会单独计算累加值,不会和之前的True块混淆。
  • 最后将False对应的行计数器重置为0,完全匹配预期结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 19:47:40