In a low-level function that is called many times, I need to do the equivalent of python's list.index, but with a numpy array. The function needs to return when it finds the first value, and raise ValueError otherwise. Something like:
>>> a = np.array([1, 2, 3]) >>> np_index(a, 1) 0 >>> np_index(a, 10) Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: 10 not in array
I want to avoid a Python loop if possible. np.where
isn't an option as it always iterates through the entire array; I need something that stops once the first index is found.
EDIT: Some more specific information related to the problem.
About 90% of the time, the index I'm searching for is in the first 1/4 to 1/2 of the array. So there's potentially a factor of 2-4 speedup at stake here. The other 10% of the time the value is not in the array at all.
I've profiled things already, and the call to np.where
is the bottleneck, taking up at least 50% of the total runtime.
It is not essential that it raise a ValueError
; it just has to return something that obviously indicates that the value isn't in the array.
I will probably code up a solution in Cython, as suggested.
You can access an array element by referring to its index number. The indexes in NumPy arrays start with 0, meaning that the first element has index 0, and the second has index 1 etc.
Fancy indexing is conceptually simple: it means passing an array of indices to access multiple array elements at once. For example, consider the following array: import numpy as np rand = np. random. RandomState(42) x = rand.
python lists are 0-indexed. So the first element is 0, second is 1, so on. So if the there are n elements in a list, the last element is n-1.
See my comment on the OP's question for caveats, but in general, I would do the following:
import numpy as np a = np.array([1, 2, 3]) np.min(np.nonzero(a == 2)[0])
if the value you are looking for is not in the array, you'll get a ValueError
due to:
ValueError: zero-size array to ufunc.reduce without identity
because you are trying to take the min value of an empty array.
I would profile this code and see if it is an actual bottleneck, because in general when numpy searches through an entire array using a built-in function rather than an explicit python loop, it is relatively fast. An insistence on halting the search when it finds the first value may be functionally irrelevant.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With