在2D数组上的Numpy滚动窗口,作为具有嵌套数组作为数据值的一维数组

时间:2016-08-29 09:20:44

标签: python arrays performance numpy sliding-window

使用np.lib.stride_tricks.as_strided时,如何使用嵌套数组作为数据值来管理2D数组?是否有更好的高效方法?

具体来说,如果我有一个2D np.array,如下所示,其中1D数组中的每个数据项都是长度为2的数组:

[[1., 2.],[3., 4.],[5.,6.],[7.,8.],[9.,10.]...]

我想重塑以下内容:

[[[1., 2.],[3., 4.],[5.,6.]],
 [[3., 4.],[5.,6.],[7.,8.]],
 [[5.,6.],[7.,8.],[9.,10.]],
  ...
]

我已经看过类似的答案(例如this rolling window function),但是在使用中我不能保持内部数组/元组不受影响。

例如窗口长度为3:我尝试了shape (len(seq)+3-1, 3, 2)stride (2 * 8, 2 * 8, 8),但没有运气。也许我错过了一些明显的东西?

干杯。

编辑:使用Python内置函数很容易生成功能相同的解决方案(可以使用类似于Divakar解决方案的np.arange进行优化),但是,使用{ {1}}?根据我的理解,这可以用于高效的解决方案吗?

3 个答案:

答案 0 :(得分:4)

IIUC你可以做这样的事情 -

def rolling_window2D(a,n):
    # a: 2D Input array 
    # n: Group/sliding window length
    return a[np.arange(a.shape[0]-n+1)[:,None] + np.arange(n)]

示例运行 -

In [110]: a
Out[110]: 
array([[ 1,  2],
       [ 3,  4],
       [ 5,  6],
       [ 7,  8],
       [ 9, 10]])

In [111]: rolling_window2D(a,3)
Out[111]: 
array([[[ 1,  2],
        [ 3,  4],
        [ 5,  6]],

       [[ 3,  4],
        [ 5,  6],
        [ 7,  8]],

       [[ 5,  6],
        [ 7,  8],
        [ 9, 10]]])

答案 1 :(得分:2)

您的as_strided审判有什么问题?它对我有用。

In [28]: x=np.arange(1,11.).reshape(5,2)
In [29]: x.shape
Out[29]: (5, 2)
In [30]: x.strides
Out[30]: (16, 8)
In [31]: np.lib.stride_tricks.as_strided(x,shape=(3,3,2),strides=(16,16,8))
Out[31]: 
array([[[  1.,   2.],
        [  3.,   4.],
        [  5.,   6.]],

       [[  3.,   4.],
        [  5.,   6.],
        [  7.,   8.]],

       [[  5.,   6.],
        [  7.,   8.],
        [  9.,  10.]]])

在我第一次编辑时,我使用的是int数组,因此必须使用(8,8,4)作为步幅。

你的形状可能是错的。如果太大,它会开始在数据缓冲区的末尾看到值。

   [[  7.00000000e+000,   8.00000000e+000],
    [  9.00000000e+000,   1.00000000e+001],
    [  8.19968827e-257,   5.30498948e-313]]])

这里它只是改变显示方法,7, 8, 9, 10仍在那里。编写那些插槽可能很危险,搞乱代码的其他部分。如果用于只读目的,as_strided最好。写/集很棘手。

答案 2 :(得分:0)

您的任务类似于this one。所以我稍微改了一下。

# Rolling window for 2D arrays in NumPy
import numpy as np

def rolling_window(a, shape):  # rolling window for 2D array
    s = (a.shape[0] - shape[0] + 1,) + (a.shape[1] - shape[1] + 1,) + shape
    strides = a.strides + a.strides
    return np.lib.stride_tricks.as_strided(a, shape=s, strides=strides)

x = np.array([[1,2],[3,4],[5,6],[7,8],[9,10],[3,4],[5,6],[7,8],[11,12]])
y = np.array([[3,4],[5,6],[7,8]])
found = np.all(np.all(rolling_window(x, y.shape) == y, axis=2), axis=2)
print(found.nonzero()[0])