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

如何在Pandas中对多Symbol时间序列按5分钟粒度重采样?

多标的时间序列重采样解决方案

问题背景

我有一个包含Date、Symbol及相关行情数值的1分钟粒度时间序列DataFrame,需要将其重采样为5分钟粒度,且每个Symbol需单独处理。Symbol代表股票/期权标的代码,实际数据可能包含数百个不同的标的。

单个标的的重采样方法已掌握:

df = df.groupby(pd.Grouper(key='Date', freq='5Min')).agg({
    'Open': 'first', 
    'High': 'max', 
    'Low': 'min', 
    'Close': 'last'
}).reset_index()

但处理多标的时遇到阻碍,尝试先按Symbol分组再按时间分组,却无法实现链式调用,伪代码如下:

df.groupby('Symbol').groupby(pd.Grouper(key='Date',freq='5Min')).agg(...)

解决方案

方法1:多键分组(性能更优,推荐)

直接将Symbol与时间Grouper作为分组键传入groupby,一次性完成分组与重采样:

# 第一步:确保Date列转换为datetime类型
df['Date'] = pd.to_datetime(df['Date'])

# 多键分组+重采样
resampled_df = df.groupby([
    'Symbol',
    pd.Grouper(key='Date', freq='5Min')
]).agg({
    'Open': 'first',  # 取区间第一条记录的Open
    'High': 'max',    # 取区间内High的最大值
    'Low': 'min',     # 取区间内Low的最小值
    'Close': 'last'   # 取区间最后一条记录的Close
}).reset_index()

方法2:分组后Apply重采样(灵活度更高)

如果需要为不同标的自定义重采样逻辑,可以先按Symbol分组,再对每个分组应用单个标的的重采样逻辑:

df['Date'] = pd.to_datetime(df['Date'])

# 定义单标的重采样函数
def resample_single_symbol(group):
    return group.groupby(pd.Grouper(key='Date', freq='5Min')).agg({
        'Open': 'first',
        'High': 'max',
        'Low': 'min',
        'Close': 'last'
    }).reset_index()

# 按Symbol分组后应用函数
resampled_df = df.groupby('Symbol').apply(resample_single_symbol).reset_index(drop=True)

示例验证

使用提供的示例数据测试:

import pandas as pd

# 示例数据
sample_data = {
    'Date': {0: '2018-01-01 09:15:00',
  1: '2018-01-01 09:16:00',
  2: '2018-01-01 09:17:00',
  3: '2018-01-01 09:18:00',
  4: '2018-01-01 09:19:00',
  5: '2018-01-01 09:20:00',
  6: '2018-01-01 09:21:00',
  7: '2018-01-01 09:22:00',
  8: '2018-01-01 09:23:00',
  9: '2018-01-01 09:24:00',
  10: '2018-01-01 09:25:00',
  11: '2018-01-01 09:15:00',
  12: '2018-01-01 09:16:00',
  13: '2018-01-01 09:17:00',
  14: '2018-01-01 09:18:00',
  15: '2018-01-01 09:19:00',
  16: '2018-01-01 09:20:00',
  17: '2018-01-01 09:21:00',
  18: '2018-01-01 09:22:00',
  19: '2018-01-01 09:23:00',
  20: '2018-01-01 09:24:00',
  21: '2018-01-01 09:25:00'},
 'Open': {0: 10531.7,
  1: 10523.0,
  2: 10525.8,
  3: 10522.6,
  4: 10521.05,
  5: 10524.2,
  6: 10526.85,
  7: 10529.95,
  8: 10533.2,
  9: 10530.95,
  10: 11528.4,
  11: 11531.7,
  12: 11523.0,
  13: 11525.8,
  14: 11522.6,
  15: 11521.05,
  16: 11524.2,
  17: 11526.85,
  18: 11529.95,
  19: 11533.2,
  20: 11530.95,
  21: 11528.4},
 'High': {0: 10533.7,
  1: 10527.5,
  2: 10526.15,
  3: 10522.95,
  4: 10523.8,
  5: 10530.25,
  6: 10530.3,
  7: 10533.55,
  8: 10534.8,
  9: 10531.25,
  10: 11529.1,
  11: 11533.7,
  12: 11527.5,
  13: 11526.15,
  14: 11522.95,
  15: 11523.8,
  16: 11530.25,
  17: 11530.3,
  18: 11533.55,
  19: 11534.8,
  20: 11531.25,
  21: 11529.1},
 'Low': {0: 10518.35,
  1: 10522.25,
  2: 10522.6,
  3: 10519.65,
  4: 10520.9,
  5: 10523.65,
  6: 10526.8,
  7: 10529.95,
  8: 10530.1,
  9: 10527.6,
  10: 11526.1,
  11: 11518.35,
  12: 11522.25,
  13: 11522.6,
  14: 11519.65,
  15: 11520.9,
  16: 11523.65,
  17: 11526.8,
  18: 11529.95,
  19: 11530.1,
  20: 11527.6,
  21: 11526.1},
 'Close': {0: 10523.15,
  1: 10525.95,
  2: 10522.6,
  3: 10521.35,
  4: 10523.7,
  5: 10526.45,
  6: 10530.3,
  7: 10533.3,
  8: 10530.5,
  9: 10528.45,
  10: 11527.45,
  11: 11523.15,
  12: 11525.95,
  13: 11522.6,
  14: 11521.35,
  15: 11523.7,
  16: 11526.45,
  17: 11530.3,
  18: 11533.3,
  19: 11530.5,
  20: 11528.45,
  21: 11527.45},
 'Symbol': {0: 'A',
  1: 'A',
  2: 'A',
  3: 'A',
  4: 'A',
  5: 'A',
  6: 'A',
  7: 'A',
  8: 'A',
  9: 'A',
  10: 'B',
  11: 'B',
  12: 'B',
  13: 'B',
  14: 'B',
  15: 'B',
  16: 'B',
  17: 'B',
  18: 'B',
  19: 'B',
  20: 'B',
  21: 'B'}
}

# 转换为DataFrame
df = pd.from_dict(sample_data)

# 使用方法1处理
df['Date'] = pd.to_datetime(df['Date'])
resampled_df = df.groupby([
    'Symbol',
    pd.Grouper(key='Date', freq='5Min')
]).agg({
    'Open': 'first',
    'High': 'max',
    'Low': 'min',
    'Close': 'last'
}).reset_index()

print(resampled_df)

输出结果会包含每个标的的5分钟聚合数据,例如:

  • Symbol A的2018-01-01 09:15:00区间(09:15-09:19):Open=10531.7,High=10533.7,Low=10518.35,Close=10523.7
  • Symbol A的2018-01-01 09:20:00区间(09:20-09:24):Open=10524.2,High=10534.8,Low=10523.65,Close=10528.45
  • Symbol B的对应区间也会按相同规则单独计算

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 07:55:56