如何在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
相关产品推荐
相关产品推荐

