Judy - 7 months ago 32
Python Question

# Transform 2D array to a 3D array with overlapping strides

I would convert the 2d array into 3d with previous rows by using NumPy or native functions.

Input:

``````[[1,2,3],
[4,5,6],
[7,8,9],
[10,11,12],
[13,14,15]]
``````

Output:

``````[[[7,8,9],    [4,5,6],    [1,2,3]],
[[10,11,12], [7,8,9],    [4,5,6]],
[[13,14,15], [10,11,12], [7,8,9]]]
``````

Any one can help?
I have searched online for a while, but cannot got the answer.

Approach #1

One approach with `np.lib.stride_tricks.as_strided` that gives us a `view` into the input `2D` array and as such doesn't occupy anymore of the memory space -

``````L = 3  # window length for sliding along the first axis
s0,s1 = a.strides

shp = a.shape
out_shp = shp[0] - L + 1, L, shp[1]
strided = np.lib.stride_tricks.as_strided
out = strided(a[L-1:], shape=out_shp, strides=(s0,-s0,s1))
``````

Sample input, output -

``````In [43]: a
Out[43]:
array([[ 1,  2,  3],
[ 4,  5,  6],
[ 7,  8,  9],
[10, 11, 12],
[13, 14, 15]])

In [44]: out
Out[44]:
array([[[ 7,  8,  9],
[ 4,  5,  6],
[ 1,  2,  3]],

[[10, 11, 12],
[ 7,  8,  9],
[ 4,  5,  6]],

[[13, 14, 15],
[10, 11, 12],
[ 7,  8,  9]]])
``````

Approach #2

Alternatively, a bit easier one with `broadcasting` upon generating all of row indices -

``````In [56]: a[range(L-1,-1,-1) + np.arange(shp[0]-L+1)[:,None]]
Out[56]:
array([[[ 7,  8,  9],
[ 4,  5,  6],
[ 1,  2,  3]],

[[10, 11, 12],
[ 7,  8,  9],
[ 4,  5,  6]],

[[13, 14, 15],
[10, 11, 12],
[ 7,  8,  9]]])
``````
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download