5

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.

cs95
  • 379,657
  • 97
  • 704
  • 746
Judy
  • 61
  • 3
  • 2
    I think I understand what you want, but it is in no way related to what you wrote in the question. What have you done so far? Please post your code. – DYZ Aug 18 '17 at 04:22
  • 1
    @DYZ Not sure where the confusion is. OP has listed the 2D input and the expected 3D output that has rows picked up from the 2D input that are current ones and their previous one, again as listed in the expected output. – Divakar Aug 18 '17 at 04:56

2 Answers2

7

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]]])
Divakar
  • 218,885
  • 19
  • 262
  • 358
4

How about a list comprehension?

In [144]: np.array([l[i:i + 3][::-1] for i in range(0, len(l) - 2)])
Out[144]: 
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]]])
cs95
  • 379,657
  • 97
  • 704
  • 746