Subsetting an np array

Two questions on subsetting an np array:
(1)

a = np.array([-1, 0.25, 0.5, 1, 2, 5, 10, 20, 30])
a[(a > 1) & (a <20)]
>>array([ 2.,  5., 10.])

Is there any shorter way to write? This does not work:

a[1< a < 20]

(2)
I want to store the indices for future use. Is there any better ways? I got an warning from here.

id1 = [(a > 1) & (a <20)]
a[id1]


/var/folders/b4/db1qr8cn127_gkbtlsjb35w00000gn/T/ipykernel_17312/3816891839.py:1: FutureWarning: Using a non-tuple sequence for multidimensional indexing is deprecated; use `arr[tuple(seq)]` instead of `arr[seq]`. In the future this will be interpreted as an array index, `arr[np.array(seq)]`, which will result either in an error or a different result.
  a[id1]
Out[143]:
array([ 2.,  5., 10.])

(1) The reason why 1 < a < 20 doesn’t work for numpy is that 1 < a < 20 in Python is basically short for (1 < a) and (a < 20), but 1 < a and a < 20 both return arrays and Python’s and wants to know whether its arguments are true or false, whereas numpy would like it to work elementwise. The workaround for and is to use &, but then you can’t chain the comparisons.

(2) Drop the [...], which are putting the array in a list. Write id1 = (a > 1) & (a <20) instead.

2 Likes

id1 = (a > 1) & (a <20)

will give you a boolean array, not the indexes – often refered to as a mask – but it will work as you want it to.

NOTE: this is standard Python – id1 = (a > 1) & (a <20) is an expression – when evaluated, it returns a value. In this case, that value can be used to index a numpy array, so:

mask = id1 = (a > 1) & (a <20)
a[mask]

is the same as:

a[id1 = (a > 1) & (a <20)]
1 Like