views:

7527

answers:

6

I know there is a method for python list to return the first index of something

l = list(1,2,3)
l.index(2)
>>>  1

Is there something like that for numpy arrays?

Thanks for your help :)

+2  A: 

There are lots of operations in numpy that could perhaps be put together to accomplish this. This will return indices of elements equal to item:

numpy.nonzero(array - item)

You could then take the first elements of the lists to get a single element.

Ned Batchelder
wouldn't that give the indices of all elements that are *not* equal to item?
Autoplectic
Yeah, this is close, but gives the not equals...
Alex
+2  A: 

to index on any criteria, you can so something like the following:

In [1]: from numpy import *
In [2]: x = arange(125).reshape((5,5,5))
In [3]: y = indices(x.shape)
In [4]: locs = y[:,x >= 120] # put whatever you want in place of x >= 120
In [5]: pts = hsplit(locs, len(locs[0]))
In [6]: for pt in pts:
   .....:         print(', '.join(str(p[0]) for p in pt))
4, 4, 0
4, 4, 1
4, 4, 2
4, 4, 3
4, 4, 4

[edit] and here's a quick function to do what list.index() does, except doesn't raise an exception if it's not found. beware -- this is probably very slow on large arrays. you can probably monkeypatch this on to arrays if you'd rather use it as a method.

def ndindex(ndarray, item):
    if len(ndarray.shape) == 1:
        try:
            return [ndarray.tolist().index(item)]
        except:
            pass
    else:
        for i, subarray in enumerate(ndarray):
            try:
                return [i] + ndindex(subarray, item)
            except:
                pass
In [1]: ndindex(x, 103)
Out[1]: [4, 0, 3]
Autoplectic
+11  A: 

Yes, here is the answer given a Numpy array, array, and a value, item, to search for.

 itemindex=numpy.where(array==item)

The result is a tuple with first all the row indices, then all the column indices. For example if array is two dimensions and it contained your item at two locations then array[itemindex[0][0]][itemindex[1][0]] would be equal to your item and so would array[itemindex[0][1]][itemindex[1][1]].

Alex
+3  A: 

If you're going to use this as an index into something else, you can use boolean indices if the arrays are broadcastable; you don't need explicit indices. The absolute simplest way to do this is to simply index based on a truth value.

other_array[first_array == item]

Any boolean operation works:

a = numpy.arange(100)
other_array[first_array > 50]

The nonzero method takes booleans, too:

index = numpy.nonzero(first_array == item)[0][0]

The two zeros are for the tuple of indices (assuming first_array is 1D) and then the first item in the array of indices.

Matt
+3  A: 

If you need the index of the first occurrence of only one value, you can use nonzero (or where, which amounts to the same thing in this case):

>>> t = array([1, 1, 1, 2, 2, 3, 8, 3, 8, 8])
>>> nonzero(t == 8)
(array([6, 8, 9]),)
>>> nonzero(t == 8)[0][0]
6

If you need the first index of each of many values, you could obviously do the same as above repeatedly, but there is a trick that may be faster. The following finds the indices of the first element of each subsequence:

>>> nonzero(r_[1, diff(t)[:-1]])
(array([0, 3, 5, 6, 7, 8]),)

Notice that it finds the beginning of both subsequence of 3s and both subsequences of 8s:

[1, 1, 1, 2, 2, 3, 8, 3, 8, 8]

So it's slightly different than finding the first occurrence of each value. In your program, you may be able to work with a sorted version of t to get what you want:

>>> st = sorted(t)
>>> nonzero(r_[1, diff(st)[:-1]])
(array([0, 3, 5, 7]),)
Vebjorn Ljosa
A: 

why there is not a function for such a basic task? something like index in list I mean.

ramon