8

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.

1
  • If you are using Python2, you can use xrange instead of range Commented Jul 9, 2013 at 21:18

3 Answers 3

12

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))
Sign up to request clarification or add additional context in comments.

3 Comments

Cool! it works. The other thing I need to do is to mirror in the first dimension. swap a[1, :, :] and a[3, :, :]. Is there a function for this?
@Mohammad Moghimi, If I understand your question correctly, you can use flipud to flip the array about the horizontal axis. a[::-1,:,:] should also work.
+1 Probably the best option. For completeness, there is also the option (which I believe is actually called by np.rollaxis) of doing np.transpose(im, (2, 0, 1)). As an aside note, np.rollaxis or np.transpose return a view of the original data, but when calling flatten on that view, a copy is likely to be triggered.
8
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()

Comments

2

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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.