[Numpy-discussion] Using array mask swaps array axes

Sebastian Berg sebastian at sipsolutions.net
Wed Oct 16 12:28:23 EDT 2013

On Wed, 2013-10-16 at 11:50 -0400, Benjamin Root wrote:
> On Wed, Oct 16, 2013 at 11:39 AM, Chad Kidder <cckidder at gmail.com>
> wrote:
>         Just found what should be a bug in 1.7.1.  I'm running
>         python(x,y) on windows here:
>         >>> dataMatrix[ii,:,mask].shape
>         (201, 23)
>         >>> dataMatrix[ii,:,:].shape
>         (23, 201)
>         >>> dataMatrix.shape
>         (24, 23, 201)
>         >>> mask
>         array([ True,  True,  True,  True,  True,  True,  True,  True,
>         True,
>                 ...
>                 True,  True,  True], dtype=bool)
>         using a mask should not change the order of the dimensions.
>         Is there a reason for this behavior, and if so, how do I avoid
>         it in the future?  Thanks
>              --Chad Kidder
> Chad,
> The issue here is one where there is the mixing of fancy indexing (I
> presume that is what "ii" is), slicing and boolean indexing. If I
> remember correctly, the changing of the dimension orders was an
> inadvertent byproduct of handing all this array accessing methods in
> one shot. I think this was addressed in 1.8. Sorry for being very
> brief and vague, hopefully someone else who understands what the
> resolution was can fill in.
Yes, in fact `ii` can just be a normal integer, since an integer *is*
considered an advanced/fancy index (in the sense that it forces
transposing, not in the sense that it forces a copy by itself, so
integers are *both* advanced and view based indices!).

This is how advanced/fancy indexing works, there is `np.ix_` which helps
in some cases, but not exactly for your problem. For a more detailed
description of fancy indexing check:

You have a slice between the mask and the integer `arr[1, :, mask]`,
which means the `mask` result dimension is transposed to the front. It
would not be if it was `arr[:, 1, mask]` (since numpy can actually guess
where it came from in that case).

Since you seem to always have exactly one advanced (mask) index, in your
example, the simplest solution is probably:
(first view based slicing, then the advanced boolean index. Since the
first part (if `ii` is an integer) will not copy the data, this will
also work for assignments).

- Sebastian

> Cheers!
> Ben Root
> _______________________________________________
> NumPy-Discussion mailing list
> NumPy-Discussion at scipy.org
> http://mail.scipy.org/mailman/listinfo/numpy-discussion

More information about the NumPy-Discussion mailing list