【发布时间】:2019-02-08 11:52:31
【问题描述】:
我正在预处理一个时间序列数据集,将其形状从 2 维(数据点、特征)更改为 3 维(数据点、time_window、特征)。
在这种透视图中,时间窗口(有时也称为回溯)表示作为输入变量参与预测下一个时间段的先前时间步/数据点的数量。换句话说,时间窗是机器学习算法考虑到未来单个预测的过去数据量。
这种方法(或至少在我的实现中)的问题在于它在内存使用方面的效率非常低,因为它会在窗口中带来数据冗余,从而导致输入数据变得非常繁重。
这是我迄今为止一直在使用的函数,用于将输入数据重塑为 3 维结构。
from sys import getsizeof
def time_framer(data_to_frame, window_size=1):
"""It transforms a 2d dataset into 3d based on a specific size;
original function can be found at:
https://machinelearningmastery.com/time-series-prediction-lstm-recurrent-neural-networks-python-keras/
"""
n_datapoints = data_to_frame.shape[0] - window_size
framed_data = np.empty(
shape=(n_datapoints, window_size, data_to_frame.shape[1],)).astype(np.float32)
for index in range(n_datapoints):
framed_data[index] = data_to_frame[index:(index + window_size)]
print(framed_data.shape)
# it prints the size of the output in MB
print(framed_data.nbytes / 10 ** 6)
print(getsizeof(framed_data) / 10 ** 6)
# quick and dirty quality test to check if the data has been correctly reshaped
test1=list(set(framed_data[0][1]==framed_data[1][0]))
if test1[0] and len(test1)==1:
print('Data is correctly framed')
return framed_data
有人建议我使用numpy's strides trick 来克服此类问题并减少重新整形数据的大小。不幸的是,到目前为止我在这个主题上找到的任何资源都集中在在二维数组上实现这个技巧,就像 excellent tutorial 一样。我一直在努力解决涉及 3 维输出的用例。这是我得出的最好的;但是,它既没有成功减小 framed_data 的大小,也没有正确地对数据进行构图,因为它没有通过质量测试。
我很确定我的错误在于我没有完全理解的 strides 参数。 new_strides 是我设法成功提供给 as_strided 的唯一值。
from numpy.lib.stride_tricks import as_strided
def strides_trick_time_framer(data_to_frame, window_size=1):
new_strides = (data_to_frame.strides[0],
data_to_frame.strides[0]*data_to_frame.shape[1] ,
data_to_frame.strides[0]*window_size)
n_datapoints = data_to_frame.shape[0] - window_size
print('striding.....')
framed_data = as_strided(data_to_frame,
shape=(n_datapoints, # .flatten() here did not change the outcome
window_size,
data_to_frame.shape[1]),
strides=new_strides).astype(np.float32)
# it prints the size of the output in MB
print(framed_data.nbytes / 10 ** 6)
print(getsizeof(framed_data) / 10 ** 6)
# quick and dirty test to check if the data has been correctly reshaped
test1=list(set(framed_data[0][1]==framed_data[1][0]))
if test1[0] and len(test1)==1:
print('Data is correctly framed')
return framed_data
任何帮助将不胜感激!
【问题讨论】:
-
我编辑了这个问题,因为我实际上转换为 float32 以节省空间。我不知道它是否会改变什么
标签: python numpy data-structures time-series