使用 NumPy 步幅沿 2D 数组的最后一个轴滑动 windows 以给出 3D 数组

Sliding windows along last axis of a 2D array to give a 3D array using NumPy strides

我正在尝试使用 numpy.lib.stride_tricks 中的函数 as_strided 从更大的二维数组中提取子系列,但我很难找到为 strides 编写的正确内容参数。

假设我有一个矩阵 m,其中包含 5 个长度为 (a=)10 的一维数组。我想为 m.

中的每个一维数组提取长度为 (b=)4 的子一维数组
import numpy
from numpy.lib.stride_tricks import as_strided

a, b = 10, 4
m = numpy.array([range(i,i+a) for i in range(5)])

# first try
sub_m = as_strided(m, shape=(m.shape[0], m.shape[1]-b+1, b))
print sub_m.shape # (5,7,4) which is what i expected
print sub_m[-1,-1,-1] # Some unexpected strange number: 8227625857902995061

# second try with strides argument
sub_m = as_strided(m, shape=(m.shape[0], m.shape[1]-b+1, b), strides=(m.itemize,m.itemize,m.itemize))
# gives error, see below

AttributeError: 'numpy.ndarray' object has no attribute 'itemize'

如您所见,我在第一次尝试时就成功地获得了 sub_m 的正确形状。但是我在 strides=()

中找不到要写的内容

参考资料:

m = [[ 0  1  2  3  4  5  6  7  8  9]
 [ 1  2  3  4  5  6  7  8  9 10]
 [ 2  3  4  5  6  7  8  9 10 11]
 [ 3  4  5  6  7  8  9 10 11 12]
 [ 4  5  6  7  8  9 10 11 12 13]]

预期输出:

sub_n = [
         [[0 1 2 3] [1 2 3 4] ... [5 6 7 8] [6 7 8 9]]
         [[1 2 3 4] [2 3 4 5] ... [6 7 8 9] [7 8 9 10]]
         [[2 3 4 5] [3 4 5 6] ... [7 8 9 10] [8 9 10 11]]
         [[3 4 5 6] [4 5 6 7] ... [8 9 10 11] [9 10 11 12]]
         [[4 5 6 7] [5 6 7 8] ... [9 10 11 12] [10 11 12 13]]
        ]

edit: 我有更多的数据,这就是我想使用as_strided(效率)

的原因

这是 np.lib.stride_tricks.as_strided -

的一种方法
def strided_lastaxis(a, L):
    s0,s1 = a.strides
    m,n = a.shape
    return np.lib.stride_tricks.as_strided(a, shape=(m,n-L+1,L), strides=(s0,s1,s1))

关于 as_strided 步幅的一些解释:

我们有 3D 步幅,沿 last/third 轴递增一个元素,因此 s1 最后一个轴步幅。第二个轴跨过相同的一个元素 "distance",因此也是 s1。对于第一个轴,步幅与数组的第一个轴步幅长度相同,因为我们移动到下一行,所以 s0 那里。

样本运行-

In [46]: a
Out[46]: 
array([[0, 5, 6, 2, 3, 6, 7, 1, 4, 8],
       [2, 1, 3, 7, 0, 3, 5, 4, 0, 1]])

In [47]: strided_lastaxis(a, L=4)
Out[47]: 
array([[[0, 5, 6, 2],
        [5, 6, 2, 3],
        [6, 2, 3, 6],
        [2, 3, 6, 7],
        [3, 6, 7, 1],
        [6, 7, 1, 4],
        [7, 1, 4, 8]],

       [[2, 1, 3, 7],
        [1, 3, 7, 0],
        [3, 7, 0, 3],
        [7, 0, 3, 5],
        [0, 3, 5, 4],
        [3, 5, 4, 0],
        [5, 4, 0, 1]]])