Home > front end >  How can I reshape a numpy array in a certain way without using a loop?
How can I reshape a numpy array in a certain way without using a loop?

Time:11-01

I have been trying to reshape a numpy array by using not more than one loop or even better no loop at all. But after several trials with np.reshape() and np.transpose(), I still do not have a clue how to transform an array like this:

array([[1,2,6,3,2,5],
      [9,4,7,3,2,6],
      [8,4,6,3,2,6],
      [9,5,0,4,5,2],
      [0,5,2,6,4,2],
      [8,6,2,5,7,4]])

into an array like this:

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

I see the pattern is,

# original
[[x11, x12, x13, x14, x15, x16],          
[x21, x22, x23, x24, x25, x26],                 
[x31, x32, x33, x34, x35, x36],       
[x41, x42, x43, x44, x45, x46],          
[x51, x52, x53, x54, x55, x56],          
[x61, x62, x63, x64, x65, x66]]

# result
[[x11, x12, x21, x22, x31, x32, x41, x42, x51, x52, x61, x62],
[x13, x14, x23, x23, x33, x34, x43, x44, x53, x54, x63, x64],
[x15, x16, x25, x26, x35, x36, x45, x46, x55, x56, x65, x66]]        

but my biggest problem is to connect to rows like shown above, especially by using vectorization instead of loops. But I was not even able to do it with one Loop. I needed two.

As I said, I tried many things. For example, I reshaped the original array to

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

From there I had no clue how to work with the rows to get the desired array.

I also tried to instantly reshape the array to match the desired shape, but then I also struggled to make the values match my desired result.

CodePudding user response:

Note that reshape cannot change the order of the elements in an array, only the strides. But it's quite straightforward to do with sliding_window_view. Of course we just want every other pair of columns, hence the ::window[1], and finalyl you want the pairs of columns as one row, hence the reshape.

window = (a.shape[0], 2)
c = np.lib.stride_tricks.sliding_window_view(a, window)[:, ::window[1], ...].reshape(-1, window[0]*window[1])

CodePudding user response:

We can use a simple approach if we know the dimensions of the array:

arr = np.array([[1,2,6,3,2,5],
[9,4,7,3,2,6],
[8,4,6,3,2,6],
[9,5,0,4,5,2],
[0,5,2,6,4,2],
[8,6,2,5,7,4]])

d1, d2= arr.shape
np.reshape(np.split(arr, d1//2,axis=1),(d1//2,d2*2))

CodePudding user response:

There are plenty of ways to do this, but directly reshaping is not one of it. In your case I would do as

# let a be your input array
a = np.array( 
    [
    [1,2,6,3,2,5],
    [9,4,7,3,2,6],
    [8,4,6,3,2,6],
    [9,5,0,4,5,2],
    [0,5,2,6,4,2],
    [8,6,2,5,7,4]]
)

np.concatenate([a[:, :2] , a[:, 2:4], a[:, 4:]]).reshape(-1,12)

array([[1, 2, 9, 4, 8, 4, 9, 5, 0, 5, 8, 6],
       [6, 3, 7, 3, 6, 3, 0, 4, 2, 6, 2, 5],
       [2, 5, 2, 6, 2, 6, 5, 2, 4, 2, 7, 4]])
  • Related