Pandas如何正确为跨日自定义时间区间设置分组索引
Pandas自定义跨日时间区间分组实现方案
直接用pandas原生时间偏移逻辑即可实现「当日20:00至次日13:30为同一分组」的需求,不需要逐行拆分日期、时间字段做累计求和,以下是两种可直接复用的实现方式:
方法1:时间偏移打标(性能最优,推荐)
核心逻辑:把所有时间戳统一向前偏移20小时,原本跨自然日的同区间数据会落到同一个自然日维度下,直接按天归一即可生成连续的分组ID,全向量化运算比逐行遍历效率高1~2个数量级。
import pandas as pd import datetime # 先确保date列转为标准datetime格式,设为索引简化时间操作 new = new.copy() new['date'] = pd.to_datetime(new['date']) new = new.set_index('date') # 核心:偏移20小时后按天取整,再因子化生成连续独立索引 new['session_id'] = (new.index - pd.Timedelta(hours=20)).floor('d').factorize()[0]
针对你提供的样例数据,分组结果完全符合预期:
2016-01-04 13:15:00归入前序区间(1月3日20:00-1月4日13:30)2016-01-04 20:00:00到2016-01-05 11:45:00全部归入同一区间(1月4日20:00-1月5日13:30),ID一致- 自动跳过周末、节假日等无数据的断层,不会出现ID错配
方法2:修正Grouper参数实现
你之前用pd.Grouper(freq='17hours')不生效的原因是:固定频率分组默认从时间序列的最早零点开始计算偏移,没有对齐你要的20:00区间起点,补上offset参数指定对齐起点即可:
# 区间总时长为17小时30分,offset指定分组起点对齐到每日20:00 new['session_id_grouper'] = new.groupby( pd.Grouper(freq='17h30min', offset='20h') ).ngroup()
附:原有代码优化
你之前写的非交易时段筛选函数可以去掉冗余的副本创建、逐行列表推导逻辑,用pandas原生向量化接口简化:
def get_out_of_market_data(data): dt_col = pd.to_datetime(data['date']) time_part = dt_col.dt.time # 筛选<13:30 或 >=20:00的非交易时段 filter_cond = (time_part < datetime.time(hour=13, minute=30)) | (time_part >= datetime.time(hour=20, minute=0)) return data[filter_cond]
内容的提问来源于stack exchange,提问作者Jackintosh
相关产品推荐
相关产品推荐

