我有一个形状为 (6,2) 的 Numpy 数组:
[[ 0, 1],
[10,11],
[20,21],
[30,31],
[40,41],
[50,51]]
我需要一个步长为 1
和窗口大小为 3
的滑动窗口,如下所示:
[[ 0, 1,10,11,20,21],
[10,11,20,21,30,31],
[20,21,30,31,40,41],
[30,31,40,41,50,51]]
我正在寻找一个 Numpy 解决方案。如果您的解决方案可以参数化原始数组的形状以及窗口大小和步长,那就太好了。
我找到了这个相关的答案 Using strides for an efficient moving average filter但我看不到如何在那里指定步长以及如何将窗口从 3d 折叠到连续的 2d 数组。还有这个Rolling or sliding window iterator?但那是在 Python 中,我不确定它的效率如何。此外,它支持元素,但如果每个元素都有多个特征,它最终不会将它们连接在一起。
最佳答案
您可以使用精美的索引在 numpy 中创建矢量化滑动窗口。
>>> import numpy as np
>>> a = np.array([[00,01], [10,11], [20,21], [30,31], [40,41], [50,51]])
>>> a
array([[ 0, 1],
[10, 11],
[20, 21], #define our 2d numpy array
[30, 31],
[40, 41],
[50, 51]])
>>> a = a.flatten()
>>> a
array([ 0, 1, 10, 11, 20, 21, 30, 31, 40, 41, 50, 51]) #flattened numpy array
>>> indexer = np.arange(6)[None, :] + 2*np.arange(4)[:, None]
>>> indexer
array([[ 0, 1, 2, 3, 4, 5],
[ 2, 3, 4, 5, 6, 7], #sliding window indices
[ 4, 5, 6, 7, 8, 9],
[ 6, 7, 8, 9, 10, 11]])
>>> a[indexer]
array([[ 0, 1, 10, 11, 20, 21],
[10, 11, 20, 21, 30, 31], #values of a over sliding window
[20, 21, 30, 31, 40, 41],
[30, 31, 40, 41, 50, 51]])
>>> np.sum(a[indexer], axis=1)
array([ 63, 123, 183, 243]) #sum of values in 'a' under the sliding window.
解释这段代码在做什么。
np.arange(6)[None, :]
创建行向量 0 到 6,np.arange(4)[:, None]
创建列向量 0 到 4。这会产生一个 4x6 矩阵,其中每一行(其中六个)代表一个窗口,行数(其中四个)代表窗口的数量。 2 的倍数使滑动窗口一次滑动 2 个单位,这是在每个元组上滑动所必需的。使用 numpy 数组切片,您可以将滑动窗口传递到展平的 numpy 数组中,并像 sum 一样对它们进行聚合。
关于python - M×N 形状 numpy.ndarray 的滑动窗口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15722324/