提取 numpy 数组的滞后特征(+ 扩展维度)|用 stride=1 重塑 numpy 数组
extracting lag features of numpy array (+ expand dimension) | reshape numpy array with stride=1
我有一个形状为 (#timestamp,#features)
的时间序列数据数组。我想提取每一行 (timestamp
) n_lags
(前几行)并重塑数组,使我的形状为 (#samples, #lags+now,#features)
Keras 的 LSTM 层的输入。
考虑这个玩具示例:
import numpy as np
n_rows = 6
n_feat= 3
n_lag = 2
a = np.array(range(n_rows*n_feat)).reshape(n_rows, n_feat)
>>> a.shape = (6, 3)
>>> a = array([[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11],
[12, 13, 14],
[15, 16, 17]])
通过遍历行,我实现了预期输出:
b = np.empty(shape=(0, (n_lag + 1), n_feat))
for idx, row in enumerate(a):
temp = np.expand_dims(a[max(0, idx-n_lag):idx+1, :], 0)
if temp.shape[1:] == b.shape[1:]:
b = np.append(b, temp, axis=0)
>>> b.shape = (4, 3, 3)
>>> b = array([[[ 0., 1., 2.],
[ 3., 4., 5.],
[ 6., 7., 8.]],
[[ 3., 4., 5.],
[ 6., 7., 8.],
[ 9., 10., 11.]],
[[ 6., 7., 8.],
[ 9., 10., 11.],
[12., 13., 14.]],
[[ 9., 10., 11.],
[12., 13., 14.],
[15., 16., 17.]]])
注意:前n_lags-1
行没有足够的数据,将在最终输出中被丢弃
问题:
我想知道是否有比遍历行更优雅/更好的方法。
您可以为此使用新的 np.lib.stride_tricks.sliding_window_view
n_rows = 6
n_feat= 3
n_lag = 2
a = np.array(range(n_rows*n_feat)).reshape(n_rows, n_feat)
b = np.lib.stride_tricks.sliding_window_view(a, window_shape=(n_feat, n_feat))
b
输出:
array([[[[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8]]],
[[[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11]]],
[[[ 6, 7, 8],
[ 9, 10, 11],
[12, 13, 14]]],
[[[ 9, 10, 11],
[12, 13, 14],
[15, 16, 17]]]])
b
只会改变 a
的形状和步幅,因此它会多次包含 a
的相同内存位置。换句话说,不需要分配新的数组。
我有一个形状为 (#timestamp,#features)
的时间序列数据数组。我想提取每一行 (timestamp
) n_lags
(前几行)并重塑数组,使我的形状为 (#samples, #lags+now,#features)
Keras 的 LSTM 层的输入。
考虑这个玩具示例:
import numpy as np
n_rows = 6
n_feat= 3
n_lag = 2
a = np.array(range(n_rows*n_feat)).reshape(n_rows, n_feat)
>>> a.shape = (6, 3)
>>> a = array([[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11],
[12, 13, 14],
[15, 16, 17]])
通过遍历行,我实现了预期输出:
b = np.empty(shape=(0, (n_lag + 1), n_feat))
for idx, row in enumerate(a):
temp = np.expand_dims(a[max(0, idx-n_lag):idx+1, :], 0)
if temp.shape[1:] == b.shape[1:]:
b = np.append(b, temp, axis=0)
>>> b.shape = (4, 3, 3)
>>> b = array([[[ 0., 1., 2.],
[ 3., 4., 5.],
[ 6., 7., 8.]],
[[ 3., 4., 5.],
[ 6., 7., 8.],
[ 9., 10., 11.]],
[[ 6., 7., 8.],
[ 9., 10., 11.],
[12., 13., 14.]],
[[ 9., 10., 11.],
[12., 13., 14.],
[15., 16., 17.]]])
注意:前n_lags-1
行没有足够的数据,将在最终输出中被丢弃
问题: 我想知道是否有比遍历行更优雅/更好的方法。
您可以为此使用新的 np.lib.stride_tricks.sliding_window_view
n_rows = 6
n_feat= 3
n_lag = 2
a = np.array(range(n_rows*n_feat)).reshape(n_rows, n_feat)
b = np.lib.stride_tricks.sliding_window_view(a, window_shape=(n_feat, n_feat))
b
输出:
array([[[[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8]]],
[[[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11]]],
[[[ 6, 7, 8],
[ 9, 10, 11],
[12, 13, 14]]],
[[[ 9, 10, 11],
[12, 13, 14],
[15, 16, 17]]]])
b
只会改变 a
的形状和步幅,因此它会多次包含 a
的相同内存位置。换句话说,不需要分配新的数组。