Python Reshape 3d array into 2d

It looks like you can use numpy.transpose and then reshape, like so -

data.transpose(2,0,1).reshape(-1,data.shape[1])

Sample run -

In [63]: data
Out[63]: 
array([[[  1.,  20.],
        [  2.,  21.],
        [  3.,  22.],
        [  4.,  23.]],

       [[  5.,  24.],
        [  6.,  25.],
        [  7.,  26.],
        [  8.,  27.]],

       [[  9.,  28.],
        [ 10.,  29.],
        [ 11.,  30.],
        [ 12.,  31.]]])

In [64]: data.shape
Out[64]: (3, 4, 2)

In [65]: data.transpose(2,0,1).reshape(-1,data.shape[1])
Out[65]: 
array([[  1.,   2.,   3.,   4.],
       [  5.,   6.,   7.,   8.],
       [  9.,  10.,  11.,  12.],
       [ 20.,  21.,  22.,  23.],
       [ 24.,  25.,  26.,  27.],
       [ 28.,  29.,  30.,  31.]])

In [66]: data.transpose(2,0,1).reshape(-1,data.shape[1]).shape
Out[66]: (6, 4)

To get back original 3D array, use reshape and then numpy.transpose, like so -

In [70]: data2D.reshape(np.roll(data.shape,1)).transpose(1,2,0)
Out[70]: 
array([[[  1.,  20.],
        [  2.,  21.],
        [  3.,  22.],
        [  4.,  23.]],

       [[  5.,  24.],
        [  6.,  25.],
        [  7.,  26.],
        [  8.,  27.]],

       [[  9.,  28.],
        [ 10.,  29.],
        [ 11.,  30.],
        [ 12.,  31.]]])

Using einops:

# start with (1024, 64, 100) to (1024*100, 64):
einops.rearrange('h w i -> (i h) w')

# or we could concatenate along horizontal axis to get (1024, 64 * 100):
einops.rearrange('h w i -> h (i w)')

See docs for more examples