Reshape a 3d array to a 2d array with leading points

I want to reshape this array (Python)

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

To this:

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

And then back

Couldn’t figure out how to do it with np.reshape

Its a series of height maps, and I want to interpolate each point with the corresponding one at the next map to create a smooth transition between them

>Solution :

With last correction, it seems that what you want is something like

np.moveaxis(a, 0,-1).reshape(-1,3)

Result

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

You probably know how to use reshape. It reinterprets the data as an array of as many lines as needed and 3 columns. The reason why reshape alone won’t do exactly what you want is because you would need the 0s to be consecutive in memory, then the 1s then the 2s, … Which they are not.
But that is solved by moveaxis: those 0s, 1s, 2s, … are consecutive when you iterate along axis 0 of your input array. So all you have to do is move axis 0 to the end, so that iterating the last axis does that (visiting 0s, then 1s, then 2s, …).

Note that moveaxis is very fast. Because it does not really build a new array. It is just a different view of the existing array. Some tricks with strides, so that visiting order appears changed.

Since you also asked for the other way, here it is (but it is just the same 2 operations, reversed and in reverse order. So undo the reshape, then undo the move axis)

res=np.moveaxis(a, 0,-1).reshape(-1,3) # Just to start from here
np.moveaxis(res.reshape(-1,3,3), -1, 0)

Result

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

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

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

as expected

Leave a Reply