
本文介绍在 Pandas 中为数据框新增一列,用于统计每组连续相同值的出现次数(即“连续批次频次”),而非全局去重计数或普通 groupby,适用于序列化场景如状态持续时长、连续事件标记等。
本文介绍在 pandas 中为数据框新增一列,用于统计每组**连续相同值**的出现次数(即“连续批次频次”),而非全局去重计数或普通 groupby,适用于序列化场景如状态持续时长、连续事件标记等。
在实际数据分析中,我们常需识别并量化“连续重复段”——例如传感器持续输出 0 的时段长度、用户连续点击同一按钮的次数、或日志中连续相同的错误码出现频次。这类需求无法通过 df.groupby('Value').transform('size') 实现,因为后者会将所有 0 合并统计(结果全为 4),而我们需要的是按相邻连续块分别计数。
核心思路是:先为每个连续批次生成唯一标识(group id),再按此 id 分组计数。具体步骤如下:
- 构造连续批次标识:利用 Series.ne()(不等于)比较当前值与上一行值(shift()),得到布尔序列;对该布尔序列做 cumsum(),即可生成递增的批次编号(每次值变化时 +1);
- 按批次分组并广播频次:使用该批次 ID 进行 groupby,再调用 transform('size') 将每组总行数广播至对应行。
以下是完整可运行代码示例:
import pandas as pd
# 构建示例数据(注意:原始问题中最后一行为 0,但表格仅显示到第5行;此处严格按输出示例构建6行)
data = {'Value': [0, 0, 0, 1, 1, 0]}
df = pd.DataFrame(data)
# 关键逻辑:生成连续批次ID → 分组 → 计算每批大小
df['Freq'] = df.groupby(
df['Value'].ne(df['Value'].shift()).cumsum()
)['Value'].transform('size')
print(df)输出结果:
Value Freq 0 0 3 1 0 3 2 0 3 3 1 2 4 1 2 5 0 1
✅ 注意事项:
- df['Value'].shift() 默认向上偏移一行,首行返回 NaN;ne() 与 NaN 比较结果为 True,因此第一行天然开启新批次,符合预期;
- 此方法完全基于向量化操作,高效且无需循环,适用于百万级数据;
- 若需扩展至多列联合判断连续性(如按 ['State', 'Region'] 共同连续),可改用 (df[['State','Region']] != df[['State','Region']].shift()).any(axis=1).cumsum();
- transform('size') 返回整数,确保新列 dtype 为 int64,避免隐式类型转换问题。
掌握这一技巧,可轻松处理时间序列、状态日志、工业过程监控等场景中的“连续段识别与度量”任务。


















