如何在Pandas中计算最近5行的滚动累计计数(非循环方式)
Pandas实现非循环的连续类别滚动累计计数
需求说明
针对包含类别列(如示例中的Color)的DataFrame,计算连续相同类别的滚动累计次数(即Excel中黄色列的效果),且需高效处理大型文件,避免使用循环。
示例DataFrame
先还原示例数据:
import pandas as pd data = { 'Date_time': ['2015-01-09', '2015-01-12', '2015-01-13', '2015-01-14', '2015-01-15', '2015-01-19', '2015-01-20', '2015-01-21', '2015-01-22', '2015-01-23'], 'Close': [18598.05, 18808.75, 18724.75, 18636.85, 19134.65, 19401.45, 19761.10, 19819.90, 19931.65, 20051.80], 'Color': ['Red', 'Green', 'Red', 'Red', 'Green', 'Green', 'Green', 'Green', 'Green', 'Green'] } df = pd.DataFrame(data)
实现步骤
核心思路是通过标记类别变化点→生成分组ID→分组内累计计数三步完成,全程无循环,效率拉满:
- 标记类别变化行:对比当前行与上一行的
Color值,若不同则标记为True,否则为False
df['color_change'] = df['Color'].ne(df['Color'].shift())
- 生成分组ID:对变化点标记列做累加,每出现一次变化,分组ID加1,连续相同类别的行会被分到同一组
df['group_id'] = df['color_change'].cumsum()
- 分组内累计计数:按
group_id分组后,用cumcount()生成组内序号,再加1(cumcount()从0开始计数)
df['Rolling_Count'] = df.groupby('group_id').cumcount() + 1
最终结果
执行后Rolling_Count列即为所需的滚动累计计数,结果如下:
| Date_time | Close | Color | color_change | group_id | Rolling_Count |
|---|---|---|---|---|---|
| 2015-01-09 | 18598.05 | Red | True | 1 | 1 |
| 2015-01-12 | 18808.75 | Green | True | 2 | 1 |
| 2015-01-13 | 18724.75 | Red | True | 3 | 1 |
| 2015-01-14 | 18636.85 | Red | False | 3 | 2 |
| 2015-01-15 | 19134.65 | Green | True | 4 | 1 |
| 2015-01-19 | 19401.45 | Green | False | 4 | 2 |
| 2015-01-20 | 19761.10 | Green | False | 4 | 3 |
| 2015-01-21 | 19819.90 | Green | False | 4 | 4 |
| 2015-01-22 | 19931.65 | Green | False | 4 | 5 |
| 2015-01-23 | 20051.80 | Green | False | 4 | 6 |
简化写法(合并步骤)
如果不需要中间列,可直接一行完成:
df['Rolling_Count'] = df.groupby(df['Color'].ne(df['Color'].shift()).cumsum()).cumcount() + 1
这种方法完全利用Pandas向量化操作,无需循环,处理大型文件时性能远高于循环写法,且支持任意数量的类别值。
内容的提问来源于stack exchange,提问作者amar gupta
相关产品推荐
相关产品推荐

