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

如何在gluonts.ListDataset中使用Pandas CustomBusinessDay频率并解决报错

问题:GluonTS ListDataset 使用自定义工作日频率报错

尝试在GluonTS的gluonts.dataset.common.ListDataset中使用Pandas自定义工作日频率,编写代码如下:

freq = pd.offsets.CustomBusinessDay(calendar=SSEExchangeCalendar())
dd = ListDataset(data, freq=freq)

运行时出现报错:

File "/Users/boss/App/ssm/venv/lib/python3.12/site-packages/gluonts/dataset/common.py", line 252, in ListDataset
  return list(
         ^^^^^   File "/Users/boss/App/ssm/venv/lib/python3.12/site-packages/gluonts/dataset/common.py", line 423, in __call__
  data = t(data)
         ^^^^^^^   File "/Users/boss/App/ssm/venv/lib/python3.12/site-packages/gluonts/dataset/common.py", line 292, in __call__
  raise GluonTSDataError( gluonts.exceptions.GluonTSDataError: Error "CustomBusinessDay cannot be used with Period or PeriodDtype" occurred, when reading field "start"

原因说明

GluonTS的ListDataset内部处理频率参数时,会尝试将其转换为Pandas的Period类型,但pd.offsets.CustomBusinessDay不支持与Period/PeriodDtype配合使用,因此直接传入CustomBusinessDay对象会触发报错。

解决方法及代码示例

核心思路是提前用自定义日历过滤/生成符合要求的交易日数据,然后给ListDataset传入基础的工作日频率字符串(如'B'),而非CustomBusinessDay对象。

步骤1:生成自定义交易日历的时间序列

先通过自定义日历生成符合要求的交易日时间戳,确保数据与交易日一一对应:

import pandas as pd
from pandas_market_calendars import SSEExchangeCalendar
from gluonts.dataset.common import ListDataset

# 初始化上交所交易日历
sse_cal = SSEExchangeCalendar()

# 定义数据的时间范围,生成对应的交易日序列
start_date = pd.Timestamp('2020-01-01')
end_date = start_date + pd.DateOffset(months=6)
trading_days = sse_cal.valid_days(start_date=start_date, end_date=end_date)

# 模拟你的目标数据(长度需与trading_days一致)
target_values = [i*0.5 for i in range(len(trading_days))]

步骤2:构造ListDataset数据并初始化

将处理好的交易日数据传入ListDataset,使用基础工作日频率'B':

# 构造数据集格式
dataset_data = [
    {
        "start": trading_days[0],  # 起始交易日
        "target": target_values,
        "timestamp": trading_days.to_list()  # 可选:显式传入时间戳,避免自动生成时的偏差
    }
]

# 初始化ListDataset,使用基础工作日频率
dd = ListDataset(dataset_data, freq='B')

替代方案:直接过滤原始数据

如果已有带时间戳的原始数据,可直接用自定义日历过滤出交易日数据后再构造ListDataset:

# 假设原始数据是带时间戳的DataFrame
raw_df = pd.DataFrame({
    'timestamp': pd.date_range(start='2020-01-01', periods=100, freq='D'),
    'value': range(100)
})

# 过滤出交易日数据
raw_df['is_trading_day'] = raw_df['timestamp'].isin(sse_cal.valid_days())
trading_df = raw_df[raw_df['is_trading_day']].reset_index(drop=True)

# 构造ListDataset数据
dataset_data = [
    {
        "start": trading_df['timestamp'].iloc[0],
        "target": trading_df['value'].tolist(),
        "timestamp": trading_df['timestamp'].tolist()
    }
]

dd = ListDataset(dataset_data, freq='B')

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 22:37:05