Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

reordering of numpy arrays

Tags:

python

numpy

I want to reorder dimensions of my numpy array. The following piece of code works but it's too slow.

for i in range(image_size):
    for j in range(image_size):
        for k in range(3):
            new_im[k, i, j] = im[i, j, k]

After this, I vectorize the new_im:

new_im_vec = new_im.reshape(image_size**2 * 3)

That said, I don't need new_im and I only need to get to new_im_vec. Is there a better way to do this? image_size is about 256.

like image 962
Mohammad Moghimi Avatar asked Jul 09 '13 21:07

Mohammad Moghimi


3 Answers

Check out rollaxis, a function which shifts the axes around, allowing you to reorder your array in a single command. If im has shape i, j, k

rollaxis(im, 2)

should return an array with shape k, i, j.

After this, you can flatten your array, ravel is a clear function for this purpose. Putting this all together, you have a nice one-liner:

new_im_vec = ravel(rollaxis(im, 2))
like image 52
Kyler Brown Avatar answered Oct 31 '22 22:10

Kyler Brown


new_im = im.swapaxes(0,2).swapaxes(1,2) # First swap i and k, then i and j
new_im_vec = new_im.flatten() # Vectorize

This should be much faster because swapaxes returns a view on the array, rather than copying elements over.

And of course if you want to skip new_im, you can do it in one line, and still only flatten is doing any copying.

new_im_vec = im.swapaxes(0,2).swapaxes(1,2).flatten()
like image 8
Chris Barker Avatar answered Oct 31 '22 23:10

Chris Barker


With einops:

x = einops.rearrange(x, 'height width color -> color height width')

Pros:

  • you see how axes were ordered in input
  • you see how axes are ordered in output
  • you don't need to think about steps you need to take (and e.g. no need to remember which direction axes are rolled)
like image 1
Alleo Avatar answered Oct 31 '22 22:10

Alleo