2

Say I have the array:

 >>> import numpy as np
 >>> myarr = np.array([[1],[2],[3],[2]])

and I want to use logical indexing to return the sub-array where myarr is not equal to 2.

 >>> subarr = myarr[myarr != 2]
 >>> print subarr
 [1 3]

Thus, myarr.shape = (4,1) but subarr.shape = (2,).

Why is the size of dimension 2 being changed when the logical indexing doesn't affect dimension 2? I could easily just reshape the output, but if I need to use logical indexing often in my code, I don't want to have to always account for extra dimensions (i.e. dimensions that are obviously not relevant to the logical slice I am doing) that may have changed.

This (N,1) --> (K,) example is especially bothersome, since any logical slice of a something-by-one array must also be a something-by-one array.

I feel like there must be a cleaner way to have the NumPy slice operations leave trivial array dimensions alone. Any suggestions?

3
  • 3
    This is because logical indexing can turn rectangular arrays in non-rectangular arrays. Therefore numpy can only return a single dimensional array. Even though in the case (N,1) it will stay (N,1), special casing this would introduce an inconsistency and it would trip you up if you are doing an (N,K) array: then code would suddenly stop working if K happens to be 0. Commented Apr 12, 2012 at 21:01
  • 1
    Sure, but it seems there could be a 'sameshape' type option to this function, that when flagged as true it requires the user to give inputs upon which the logical slice preserves one of the dimensions, or something. In fact that would seem like one of the most basic and immediately neccessary ways in which to use it, lest everyone has to issue reshapes every time they want to process logical slices in the same manner that they processed the parent arrays from which the slices came. Commented Apr 12, 2012 at 21:04
  • 1
    I guess what I mean is, yes you are correct. The places where an array == 2 might not reduce down to a sensible array. But one can check whether the places you are grabbing from an array do allow for shape preservation or if they don't. And I'm very surprised that isn't already one of the most basic functions of logical slicing. Commented Apr 12, 2012 at 21:05

1 Answer 1

2

In numpy indexing with a boolean array is the same as indexing with array.nonzero(). Because array.nonzero() returns two sets of indices for a 2darray, you are in fact indexing on both the first and the second dimension:

>>> myarr = np.array([[1],[2],[3],[2]])
>>> (myarr != 2).nonzero()
(array([0, 2]), array([0, 0]))
>>> myarr[(array([0, 2]), array([0, 0]))]
array([1, 3])

What you really want is:

>>> myarr[array([0, 2])]
array([[1],
       [3]])

Which you can get by:

>>> myarr[myarr[:,0] != 2]
array([[1],
       [3]])

or:

>>> myarr[(myarr != 2).nonzero()[0]]
array([[1],
       [3]])
Sign up to request clarification or add additional context in comments.

1 Comment

Great! Exactly what I was looking for.

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.