NumPy函数sliding_window_view()使用给定的窗口形状在数组中创建一个滑动窗口视图,产生一个增加了滑动窗口维度的数据集。
sliding_window_view(x, window_shape, axis=None, *, subok=False, writeable=False)
其中参数:
x: numpy数组,为需要创建滑窗数组的多维numpy数组。
window_shape : int 或者 tuple of int,参与滑动窗口的每个轴上的窗口大小。如果axis=None,滑窗需要与输入数阵列尺寸具有相同维度。
axis:int 或者 tuple of int,可选参数,默认为None。axis为滑窗进行的维度,如果为None,默认对所有维度进行滑窗,如果不为None,可以指定维度进行滑窗。window_shape[i]将指x的i轴。如果axis是int的元组,那么window_shape[i]将指x的axis[i]轴。单整数i被视为元组(i,),此时window_shape可以赋值为整数int。
subok:布尔值,可选参数,默认为False。如果传入True,将返回子类数组,否则返回的阵列将被迫为基类数组(默认值)
writable:布尔值,可选参数,默认为False。当传入True时,允许写回视图。默认值是False的,因为应该谨慎使用:返回的视图多次包含相同的内存位置,因此写到一个位置会导致其他位置更改。
函数返回值:
view:numpy数组,为输入数组x的滑窗视图数组,滑窗维度插入到了数组的最后,并且初始的维度根据滑窗进行了裁剪,即view.shape = x_shape_trimmed + window_shape,其中“x_shape_trimmed”为“x.shape”,每个条目比相应的窗口大小减少(window_shape-1)
bottleneck提供了更快的滑窗方法 https://github.com/pydata/bottleneck
scipy.signal.fftconvolve也可以在某些滑窗情景使用
scipy.ndimage也可以生成滑窗视图
应用举例:采用源代码案例
>>>from numpy.lib.stride_tricks import sliding_window_view
>>> x = np.arange(6)
>>> x.shape
(6,)
>>> v = sliding_window_view(x, 3)
>>> v.shape
(4, 3)
>>> v
array([[0, 1, 2],
[1, 2, 3],
[2, 3, 4],
[3, 4, 5]])
This also works in more dimensions, e.g.
>>> i, j = np.ogrid[:3, :4]
>>> x = 10*i + j
>>> x.shape
(3, 4)
>>> x
array([[ 0, 1, 2, 3],
[10, 11, 12, 13],
[20, 21, 22, 23]])
>>> shape = (2,2)
>>> v = sliding_window_view(x, shape)
>>> v.shape
(2, 3, 2, 2)
>>> v
array([[[[ 0, 1],
[10, 11]],
[[ 1, 2],
[11, 12]],
[[ 2, 3],
[12, 13]]],
[[[10, 11],
[20, 21]],
[[11, 12],
[21, 22]],
[[12, 13],
[22, 23]]]])
The axis can be specified explicitly:
>>> v = sliding_window_view(x, window_shape=3, axis=0)
>>> v.shape
(1, 4, 3)
>>> v
array([[[ 0, 10, 20],
[ 1, 11, 21],
[ 2, 12, 22],
[ 3, 13, 23]]])
The same axis can be used several times. In that case, every use reduces
the corresponding original dimension:
>>> v = sliding_window_view(x, (2, 3), (1, 1))
>>> v.shape
(3, 1, 2, 3)
>>> v
array([[[[ 0, 1, 2],
[ 1, 2, 3]]],
[[[10, 11, 12],
[11, 12, 13]]],
[[[20, 21, 22],
[21, 22, 23]]]])
Combining with stepped slicing (`::step`), this can be used to take sliding
views which skip elements:
>>> x = np.arange(7)
>>> sliding_window_view(x, 5)[:, ::2]
array([[0, 2, 4],
[1, 3, 5],
[2, 4, 6]])
or views which move by multiple elements
>>> x = np.arange(7)
>>> sliding_window_view(x, 3)[::2, :]
array([[0, 1, 2],
[2, 3, 4],
[4, 5, 6]])
A common application of `sliding_window_view` is the calculation of running
statistics. The simplest example is the
`moving average <https://en.wikipedia.org/wiki/Moving_average>`_:
>>> x = np.arange(6)
>>> x.shape
(6,)
>>> v = sliding_window_view(x, 3)
>>> v.shape
(4, 3)
>>> v
array([[0, 1, 2],
[1, 2, 3],
[2, 3, 4],
[3, 4, 5]])
>>> moving_average = v.mean(axis=-1)
>>> moving_average
array([1., 2., 3., 4.])