52

I'm trying to find the indices of all elements in an array that are greater than a but less than b. It's probably just a problem with my syntax but this doesn't work:

numpy.where((my_array > a) and (my_array < b))

How should I fix this? Or is there a better way to do it?

Thanks!

ylangylang
  • 3,294
  • 11
  • 30
  • 34

1 Answers1

84

Here are two ways:

In [1]: my_array = arange(10)

In [2]: where((my_array > 3) & (my_array < 7))
Out[2]: (array([4, 5, 6]),)

In [3]: where(logical_and(my_array > 3, my_array < 7))
Out[3]: (array([4, 5, 6]),)

For the first (replacing and with &), be careful to add parentheses appropriately: & has higher precedence than the comparison operators. You can also use *, but I wouldn't recommend it: it's hacky and doesn't make for readable code.

In [4]: where((my_array > 3) * (my_array < 7))
Out[4]: (array([4, 5, 6]),)
Mark Dickinson
  • 29,088
  • 9
  • 83
  • 120
  • 2
    what do you mean with "hacky" ? and why does it always return "(array([4,5,6]),)" instead of just returning "array([4,5,6])" ? What is the idea behind the "tuple without a second thing in it"-syntax of the returned thing? – usethedeathstar Mar 21 '14 at 14:25
  • 2
    @usethedeathstar: (1) the hacky bit is subjective. I guess my issue with it is that (for me, at least) the surface reading of the code doesn't clearly match the intent. (2) For `where`, it returns a tuple because in the general case `where` operates on two `n`-dimensional arrays and returns an `n`-tuple of results; here you're seeing the special case where `n=1`. The tuple container is a bit ugly, but being inconsistent with the higher-dimensional cases would probably be uglier. (Yay! More subjectivity!) – Mark Dickinson Mar 21 '14 at 14:31
  • so since in this case, we get a 1D array, the tuple is 1 item long, and in the 2D case, you just get an "x-index" array and a "y-index" array in your tuple, showing the x,y coordinates of the points in your 2D array that are good according to the logic-composition you made? – usethedeathstar Mar 21 '14 at 14:36
  • @usethedeathstar: Yes, exactly. – Mark Dickinson Mar 21 '14 at 14:42
  • 1
    Bah: "operates on two n-dimensional arrays" should be "operates on an n-dimensional array" above. – Mark Dickinson Mar 21 '14 at 15:11