Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Numpy equivalent of list.index

Tags:

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.

like image 390
lothario Avatar asked Feb 23 '11 22:02

lothario


People also ask

Do NumPy arrays have index?

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.

What is NumPy fancy indexing?

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.

How are lists indexed in Python?

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.


1 Answers

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.

like image 58
JoshAdel Avatar answered Oct 06 '22 15:10

JoshAdel