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

如何高效将DataFrame按时间间隔拆分为子DataFrame列表(替代循环)

按时间间隔拆分DataFrame的高效实现方法

问题背景

现有如下结构的esu_tos DataFrame:

Time                    TickType    Price   Size
2023-08-13 15:10:46.166 1           4487.25 1
2023-08-13 15:10:47.375 1           4487    1
2023-08-13 15:10:54.656 1           4487.25 2
2023-08-13 15:10:57.627 1           4487    1
2023-08-13 15:10:57.628 1           4487    1
2023-08-13 15:10:57.628 1           4487    1
2023-08-13 15:11:00.759 1           4487.25 1
2023-08-13 15:11:00.759 1           4487    3
2023-08-13 15:11:01.415 1           4487    3
2023-08-13 15:11:01.416 1           4487    1

需要按指定时间间隔(如5s/1min等)拆分为子DataFrame列表,替代原有的循环切片逻辑,且最终要得到可单独处理的子数据集,而非单纯的groupby对象。

原循环实现逻辑:

interval = '5s' # 1min / 30s / 10s / 5s
st = datetime(2023,8,13,15,10)
end = datetime(2023,8,14,14,1)

rng = pd.date_range(st, end, freq = interval, inclusive='both')

d = []
d_t = []
for i, k in enumerate(rng):   
    try: 
        a = esu_tos[(esu_tos.Time >= k) & (esu_tos.Time < rng[i+1])]
    except:
        a = esu_tos[(esu_tos.Time >= k) & (esu_tos.Time <= end)]
    d.append(a)   
    d_t.append(k)

高效替代方案

方案1:利用pd.cut+groupby生成子DataFrame列表

通过矢量化操作给每条数据标记所属时间区间,再分组提取子数据集,避免循环带来的性能损耗:

import pandas as pd
from datetime import datetime

# 确保Time列为datetime类型
esu_tos['Time'] = pd.to_datetime(esu_tos['Time'])

interval = '5s'
st = datetime(2023,8,13,15,10)
end = datetime(2023,8,14,14,1)

# 生成时间区间边界
bins = pd.date_range(start=st, end=end, freq=interval, inclusive='both')
# 给每条数据分配对应的区间标签
esu_tos['interval'] = pd.cut(esu_tos['Time'], bins=bins, include_lowest=True)

# 按区间分组,转换为子DataFrame列表
d = [group for _, group in esu_tos.groupby('interval')]
# 提取各区间的起始时间
d_t = [interval_label.left for interval_label in esu_tos['interval'].cat.categories]

优势:

  • 基于pandas矢量化操作,数据量越大,性能优势越明显
  • 自动处理区间边界逻辑,无需手动捕获IndexError处理最后一个区间

方案2:保留所有区间(含空数据区间)

如果需要和原循环逻辑完全一致,保留所有时间区间(即使区间内无数据,返回空DataFrame),可以补充如下逻辑:

# 生成所有待处理的区间起始时间
all_interval_starts = bins[:-1]
# 构建包含所有区间的子DataFrame列表
d = []
d_t = []
for start_time in all_interval_starts:
    # 计算对应区间的结束时间
    end_time = start_time + pd.Timedelta(interval)
    # 切片筛选数据
    sub_df = esu_tos[(esu_tos['Time'] >= start_time) & (esu_tos['Time'] < end_time)]
    d.append(sub_df)
    d_t.append(start_time)
# 单独处理最后一个区间,确保覆盖到指定end时间
last_sub_df = esu_tos[(esu_tos['Time'] >= all_interval_starts[-1]) & (esu_tos['Time'] <= end)]
d[-1] = last_sub_df

这个方案去掉了原循环中的try-except,通过直接计算区间结束时间实现逻辑,代码更清晰可控。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 21:14:57