
本文介绍如何在 Pandas 中结合时间窗口(如每5分钟)和离散字段(如 price)进行分组,并对指定列(volume)计算组内累积和,进而筛选出累积值首次超过阈值(如100)的时间点。
本文介绍如何在 pandas 中结合时间窗口(如每5分钟)和离散字段(如 price)进行分组,并对指定列(volume)计算**组内累积和**,进而筛选出累积值首次超过阈值(如100)的时间点。
在金融或时序数据分析中,常需按固定时间粒度(如5分钟K线)与业务维度(如成交价格)联合分组,并追踪某指标(如成交量)的组内累计过程。Pandas 提供了灵活的 groupby().cumsum() 方法来高效实现这一需求。
首先,需将字符串时间列转换为 datetime 类型,以便使用时间频率操作:
import pandas as pd
data = {
'time': ['10:00', '10:01', '10:02', '10:02', '10:03', '10:04', '10:06', '10:10', '10:15'],
'price': [100, 101, 101, 103, 101, 101, 105, 106, 107],
'volume': [50, 60, 30, 80, 20, 50, 10, 40, 40]
}
df = pd.DataFrame(data)
df['time'] = pd.to_datetime('2024-04-06 ' + df['time']) # 补全年月日,生成完整 datetime
接着,使用 dt.floor('5T')(等价于 '5min')对时间向下取整至最近的5分钟边界(如 10:02 → 10:00,10:06 → 10:05),再与 'price' 组合构成多级分组键:
df['cum_volume'] = df.groupby([
df['time'].dt.floor('5T'),
'price'
])['volume'].cumsum()
该操作为每组(例如:[10:00, 101])独立计算 volume 的从前到后的累积和,而非全局或窗口滚动和。结果如下(关键行已标出):
| time | price | volume | cum_volume |
|---|---|---|---|
| 2024-04-06 10:00:00 | 100 | 50 | 50 |
| 2024-04-06 10:01:00 | 101 | 60 | 60 |
| 2024-04-06 10:02:00 | 101 | 30 | 90 |
| 2024-04-06 10:02:00 | 103 | 80 | 80 |
| 2024-04-06 10:03:00 | 101 | 20 | 110 ← 首次突破100 |
| 2024-04-06 10:04:00 | 101 | 50 | 160 |
| ... | ... | ... | ... |
最后,通过布尔索引或 query() 快速提取所有 cum_volume > 100 的记录:
result = df[df['cum_volume'] > 100]
# 或:result = df.query('cum_volume > 100')
⚠️ 注意事项:
- dt.floor('5T') 要求 time 列为 datetime64 类型,原始字符串需显式转换;
- 分组逻辑严格基于 floor 后的时间桶 + price 值,相同价格但跨时间桶的数据不会混入同一组;
- cumsum() 是按原始 DataFrame 行序在每组内累加,因此数据应预先按时间排序(本例已自然有序);若顺序混乱,建议先执行 df.sort_values('time', inplace=True);
- 若需获取“首次突破”的唯一时间点(而非全部超限行),可进一步对 result 按 time 取最小值:result['time'].min()。
此方法兼顾性能与可读性,适用于实时监控、订单流分析及高频交易信号生成等场景。











