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

Pandas实现连续1的累计求和:分组遇0或换组重置计数

实现思路与解决方案

这是一个很常见的序列分组累计问题,用 Pandas 可以通过分组+辅助块ID的方式轻松解决,我来一步步给你讲清楚实现思路和代码:

核心逻辑

我们需要按Name分组,在每个分组内对连续的1进行累计计数,当遇到0或者分组切换时重置计数。关键是先把每个连续的1序列(被0分隔)标记为独立的“块”,然后在每个块内做累计和,同时保留0的原始值。


步骤1:构造示例DataFrame

首先我们把你给出的数据转换成可测试的 Pandas DataFrame:

import pandas as pd

# 原始数据
data = [
    ["Name_A", "date1", 1],
    ["Name_A", "date2", 0],
    ["Name_A", "date3", 1],
    ["Name_A", "date4", 1],
    ["Name_A", "date5", 1],
    ["Name_B", "date6", 1],
    ["Name_B", "date7", 1],
    ["Name_B", "date8", 0],
    ["Name_B", "date9", 1],
]
df = pd.DataFrame(data, columns=["Name", "Date", "Value"])

步骤2:标记连续序列的“块ID”

按Name分组后,我们用(Value == 0).cumsum()生成每个连续序列的块ID:

  • 每当遇到0,块ID就会加1,这样每个被0分隔的连续1序列会被分到同一个块里
  • 分组切换时,块ID会自动重置(因为groupby会单独处理每个分组)
# 生成每个分组内的块ID
df["block_id"] = df.groupby("Name")["Value"].apply(lambda x: (x == 0).cumsum())

步骤3:计算每个块内的累计和

现在我们按Name和block_id双重分组,对Value做累计和:

  • 对于Value=0的行,累计和自然是0,完全符合需求
  • 对于连续的1,会在同一个块内从1开始递增计数
# 计算最终结果
df["Result"] = df.groupby(["Name", "block_id"])["Value"].cumsum()

# 移除辅助列(可选操作)
df = df.drop("block_id", axis=1)

最终结果

运行后你会得到完全符合期望的输出:

Name   Date  Value  Result
0  Name_A  date1      1       1
1  Name_A  date2      0       0
2  Name_A  date3      1       1
3  Name_A  date4      1       2
4  Name_A  date5      1       3
5  Name_B  date6      1       1
6  Name_B  date7      1       2
7  Name_B  date8      0       0
8  Name_B  date9      1       1

简化版代码(合并步骤)

如果不想保留辅助列,可以把逻辑合并成一行,更简洁:

df["Result"] = df.groupby("Name")["Value"].apply(
    lambda x: x.groupby((x == 0).cumsum()).cumsum()
)

这个方案逻辑清晰且高效,适合处理大规模的数据集。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:08:05