将多个GluonTS预测导出到熊猫数据框

时间:2020-04-24 20:29:21

标签: python pandas numpy time-series

我想使用GluonTS进行预测的多个时间序列,然后进行串联,因此我的结果是一个带有列标题datey(目标)的熊猫数据框,series(序列号)。

问题在于GluonTS会生成生成器。我可以使用next(iter(forecast_id))查看每个系列,但我想将所有预测堆叠在一起,以使其更容易导出为csv。

我如何将所有系列的预测结果堆叠到一个熊猫数据框中?

import pandas as pd 
import numpy as np 
import mxnet as mx
from mxnet import gluon
from gluonts.dataset import common
from gluonts.model.baseline import SeasonalNaivePredictor
from gluonts.trainer import Trainer
from gluonts.evaluation.backtest import make_evaluation_predictions
from gluonts.dataset.util import to_pandas

N = 10  # number of time series
T = 100  # number of timesteps
prediction_length = 24
custom_dataset = np.random.normal(size=(N, T))
start = pd.Timestamp("01-01-2019", freq='1H') 

# train dataset: cut the last window of length "prediction_length", add "target" and "start" fields
train_ds = [{'target': x, 'start': start} for x in custom_dataset[:, :-prediction_length]]
# test dataset: use the whole dataset, add "target" and "start" fields
test_ds = [{'target': x, 'start': start} for x in custom_dataset]

predictor = SeasonalNaivePredictor(
    prediction_length=prediction_length,
    season_length=24,
    freq='1H'
)

forecast_it, ts_it = make_evaluation_predictions(
    dataset=test_ds,  # test dataset
    predictor=predictor,  # predictor
    num_samples=100,  # number of sample paths we want for evaluation
)

test_entry = next(iter(forecast_it))
print(test_entry)
> gluonts.model.forecast.SampleForecast(freq="1H", info=None, item_id=None, samples=numpy.array([[-1.078548550605774, 0.3002452254295349, 0.1025903970003128, -1.6613410711288452, -0.2776057720184326, -0.020864564925432205, -1.9355241060256958, 1.0598571300506592, 0.16316552460193634, -0.9441472887992859, 2.7307169437408447, -0.35861697793006897, 0.22022956609725952, 0.8052476048469543, -1.1194337606430054, 0.05703512206673622, -1.1357367038726807, -2.544445037841797, 1.2661969661712646, 0.17130693793296814, 0.8647393584251404, -1.9620181322097778, -0.5465423464775085, 0.26572829484939575]], numpy.dtype("float32")), start_date=pandas.Timestamp("2019-01-04 04:00:00", freq="H"))

1 个答案:

答案 0 :(得分:2)

您可以像这样解压条目:

def sample_df(forecast):
    samples = forecast.samples
    ns, h = samples.shape
    dates = pd.date_range(forecast.start_date, freq=forecast.freq, periods=h)
    return pd.DataFrame(samples.T, index=dates)

这只是从SampleForecast获取各种属性。

它以预测samplesndarray开头,每个样本行一行,每个时间段一行。列数给出了预测范围h,该属性具有start_datefreq属性,可以赋予pd.date_range以构造预测dates。 / p>

然后转置samples,为每个时间段提供一行,为每个样本提供一列。可以使用重建的dates将其编入索引,并且全部准备好一个样本。

sample_df(test_entry)
#                             0
# 2019-01-04 04:00:00  0.748107
# 2019-01-04 05:00:00  1.620660
# 2019-01-04 06:00:00 -0.648520
# 2019-01-04 07:00:00  0.277669
# 2019-01-04 08:00:00 -1.010820
# ...

要处理所有结果,可以在每个DataFrame上独立运行此方法,并将其与pd.concat放在一起。

parts = [sample_df(entry).assign(entry=i)
         for i, entry in enumerate(forecast_it)]
pd.concat(parts)
#                             0  entry
# 2019-01-04 04:00:00  0.748107      0
# 2019-01-04 05:00:00  1.620660      0
# 2019-01-04 06:00:00 -0.648520      0
# 2019-01-04 07:00:00  0.277669      0
# 2019-01-04 08:00:00 -1.010820      0
# ...                       ...    ...
# 2019-01-04 23:00:00  0.999718      9
# 2019-01-05 00:00:00  0.027250      9
# 2019-01-05 01:00:00  2.030961      9
# 2019-01-05 02:00:00 -1.414711      9
# 2019-01-05 03:00:00  0.737124      9

这还会用DataFrame标记每个entry,以标记它来自哪个预测结果。

您还可以使用pd.DataFrame.melt将每个样本的一列转换为带有一列的长格式以标识样本。最后一些重命名可以使所有内容漂亮,以便以后进行分析。

long_form = pd.concat(parts).reset_index().melt(['index', 'entry'])
long_form.rename(columns={
    'index': 'ts',
    'variable': 'sample',
    'value': 'forecast',
})
#                      ts  entry sample     value
# 0   2019-01-04 04:00:00      0      0  0.748107
# 1   2019-01-04 05:00:00      0      0  1.620660
# 2   2019-01-04 06:00:00      0      0 -0.648520
# 3   2019-01-04 07:00:00      0      0  0.277669
# 4   2019-01-04 08:00:00      0      0 -1.010820
# ..                  ...    ...    ...       ...
# 235 2019-01-04 23:00:00      9      0  0.999718
# 236 2019-01-05 00:00:00      9      0  0.027250
# 237 2019-01-05 01:00:00      9      0  2.030961
# 238 2019-01-05 02:00:00      9      0 -1.414711
# 239 2019-01-05 03:00:00      9      0  0.737124

注意:该代码应适用于任意数量的示例,并为每个示例提供一列(或长格式的行)。但是这里的结果只有一个样本。有什么作用?

我通读了相关代码,无论您向make_evaluation_predictions提出什么要求,RepresentablePredictor基类都只会生成一个样本。该参数永远不会传递。该基类用于非胶粘剂预测方法,因此我想他们只是希望它们是非随机的,并且仅适合于生成单个示例。还是一个错误。