Converting a 3D numpy array to 2D without np.concatenate or np.append

Viewed 129
x = np.array[[[8, 7, 1, 0, 3],
              [2, 8, 5, 5, 2],
              [1, 1, 1, 1, 1]],

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

             [[2, 4, 0, 2, 3],
              [2, 5, 5, 3, 2],
              [1, 1, 1, 1, 1]],

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

I have a NumPy array like this and I want to convert it from 3D to 2D as I showed below.

x = np.array[[[8, 7, 1, 0, 3, 8, 4, 1, 0, 0, 2, 4, 0, 2, 3, 4, 7, 2, 8, 0],
              [2, 8, 5, 5, 2, 6, 8, 5, 5, 2, 2, 5, 5, 3, 2, 1, 3, 6, 5, 2],
              [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]

Actually my array is really big and I am having problem with working this but works with the same logic.

I can't use np.concatenate or np.append because they are working too slow.

Is there any other way to do this?

Actually I'm using this array for plotting with matplotlib.

plt.imshow(x)
plt.show()

If there is a way to plot this 3D array with matplotlib without converting it to 2D that would be great.

2 Answers

You can try using ndarray.swapaxes + ndarray.reshape.

x.swapaxes(0, 1).reshape(x.shape[1], -1)
array([[8, 7, 1, 0, 3, 8, 4, 1, 0, 0, 2, 4, 0, 2, 3, 4, 7, 2, 8, 0],
       [2, 8, 5, 5, 2, 6, 8, 5, 5, 2, 2, 5, 5, 3, 2, 1, 3, 6, 5, 2],
       [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]])

Timeit results:

In [102]: %timeit x.swapaxes(0, 1).reshape(x.shape[1], -1)                      
818 ns ± 21.9 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [103]: %timeit np.hstack(x)                                                  
6.6 µs ± 42.2 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

swapaxes + reshape here is nearly ~8x faster.

Online demo in repl.it

You can use np.hstack():

print(np.hstack(x))

Prints:

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