Question: I have a 2D NumPy array that of shape (1500, 3712). I want to find the indices of the array that have values between -10 and -40. So far I have:

```py
for item in lon_array:
    for value in item:
        if value >= -40 and value <= -10:
            find_index = np.where(lon_array == value)
            index = np.asarray(find_index).T

```

Since it is a really big array, is there any way to make this faster?

Answer: 
Assuming your `lon_array` is a NumPy array you can use the following methods:

```py
find_index = np.where(np.logical_and(lon_array >= -40, lon_arr <= -10))
index =  np.asarray(find_index).T

```

Since `np.where` takes only one condition, you can combine two to get the between condition with `np.logical_and`.

It can be done as a one-liner too:

```py
>>> lon_arr
array([[ 20, -40],
       [ 30, -30],
       [ 20, -14],
       [ 30, -30]])
>>> np.asarray(np.where(np.logical_and(lon_arr>=-40, lon_arr<=-10))).T
array([[0, 1],
       [1, 1],
       [2, 1],
       [3, 1]])

```
With `numpy.where`, you can extract the indices based on the value of your data, and keep the iterations over your data executed in the optimized `c code` on to which `numpy` is built:

```
import numpy as np

x = np.random.random(10).reshape(2, 5)
print(x)
indices = np.where(x < 0.2)  #<--- this selects the indices based on a filter
print(indices)
x[indices]

```

output:
-------

```
[[ 0.11129659  0.33608351  0.07542966  0.44118394  0.14848829]
 [ 0.8475123   0.27994122  0.91797756  0.02662857  0.52820238]]

# These are the indices produced by np.where:
# the first array contains the rows `i` and the second the columns `j`
(array([0, 0, 0, 1]), array([0, 2, 4, 3]))

array([ 0.11129659,  0.07542966,  0.14848829,  0.02662857])

```

Because you have two conditions in your filter, I suggest you use the following construct that allows to build a more complex boolean expression than what `np.where` directly accepts:

```
indices = np.where(np.logical_or(x < 0.2, x > 0.8))

```