如何将预测日销量拆解至小时级?HierarchicalForecast代码报错求助
解决hierarchicalforecast层级分配时的Series不匹配报错
错误原因
这个报错核心是层级结构表S_df中定义的所有时间序列ID(父节点+子节点)与预测结果表Y_hat_df的unique_id集合完全不匹配:
S\Y_hat=425:S_df里有425个ID(大概率是所有小时级序列ID)未出现在Y_hat_df中Y_hat\S=1:Y_hat_df里存在1个不在S_df层级结构中的无效ID
数据样例与修正代码
1. 构造符合要求的小时/日级样例数据
import pandas as pd import numpy as np # 生成0600H-2200H的小时级销量数据 dates = pd.date_range(start='2024-01-01', end='2024-01-10', freq='D') hours = [f'{h:02d}00H' for h in range(6, 23)] # 17个小时区间 hourly_data = [] for date in dates: for hour in hours: hourly_data.append({ 'unique_id': f'{date.date()}_{hour}', 'ds': date + pd.Timedelta(hour.split('H')[0] + 'h'), 'y': np.random.randint(10, 100) }) hourly_df = pd.DataFrame(hourly_data) # 聚合为日级销量数据 daily_df = hourly_df.groupby(pd.Grouper(key='ds', freq='D')).agg({'y': 'sum'}).reset_index() daily_df['unique_id'] = daily_df['ds'].dt.date.astype(str) daily_df = daily_df.rename(columns={'y': 'y_daily'})
2. 构建正确的层级关系表S_df
确保每个小时级ID对应所属的日级父ID,无遗漏或多余:
# 生成子节点(小时级)→ 父节点(日级)的映射 S_data = [] for date_str in daily_df['unique_id'].tolist(): for hour in hours: S_data.append({ 'child': f'{date_str}_{hour}', 'parent': date_str }) S_df = pd.DataFrame(S_data)
3. 生成日级预测并补全Y_hat_df
必须让Y_hat_df包含S_df中所有ID(日级+小时级):
# 模拟日级预测(替换为你的实际预测模型) daily_forecast = daily_df.copy() daily_forecast['y_hat'] = daily_forecast['y_daily'].rolling(3).mean().fillna(daily_forecast['y_daily'].mean()) # 补全小时级ID到Y_hat_df,先填充NaN(TopDown会自动分配) hourly_hat = hourly_df[['unique_id', 'ds']].copy() hourly_hat['y_hat'] = np.nan # 合并日级预测与补全的小时级行 Y_hat_df = pd.concat([daily_forecast[['unique_id', 'ds', 'y_hat']], hourly_hat], ignore_index=True) # 检查ID匹配(可选,提前排查问题) all_S_ids = set(S_df['child'].tolist() + S_df['parent'].tolist()) all_Y_hat_ids = set(Y_hat_df['unique_id'].tolist()) assert all_S_ids == all_Y_hat_ids, "S_df与Y_hat_df的ID集合不匹配,请检查"
4. 准备历史数据并执行层级分配
from hierarchicalforecast.core import HierarchicalReconciliation from hierarchicalforecast.methods import TopDown # 合并小时级与日级历史数据为Y_df hourly_Y = hourly_df[['unique_id', 'ds', 'y']] daily_Y = daily_df.rename(columns={'y_daily': 'y'})[['unique_id', 'ds', 'y']] Y_df = pd.concat([hourly_Y, daily_Y], ignore_index=True) # 初始化调和器,使用历史占比分配日级预测到小时级 hrec = HierarchicalReconciliation(reconcilers=[TopDown(method='forecast_proportions')]) # 执行层级分配 Y_rec_df = hrec.reconcile(Y_df=Y_df, Y_hat_df=Y_hat_df, S_df=S_df) # 查看分配后的小时级预测结果 hourly_rec_results = Y_rec_df[Y_rec_df['unique_id'].str.contains('_')] print(hourly_rec_results[['unique_id', 'ds', 'y_hat_TopDown']])
关键修正点
- ID集合完全对齐:确保
S_df中所有父/子ID都存在于Y_hat_df中,同时Y_hat_df无额外无效ID - 历史数据覆盖全层级:
Y_df必须包含小时级和日级的历史销量,供TopDown方法计算历史占比 - 补全小时级预测行:即使小时级无初始预测,也要在
Y_hat_df中保留对应行,库会自动用日级预测按占比分配
内容的提问来源于stack exchange,提问作者karan
相关产品推荐
相关产品推荐

