Getting the Indices of Several Elements in a Numpy Array at Once

Getting the indices of several elements in a NumPy array at once

You could use in1d and nonzero (or where for that matter):

>>> np.in1d(b, a).nonzero()[0]
array([0, 1, 4])

This works fine for your example arrays, but in general the array of returned indices does not honour the order of the values in a. This may be a problem depending on what you want to do next.

In that case, a much better answer is the one @Jaime gives here, using searchsorted:

>>> sorter = np.argsort(b)
>>> sorter[np.searchsorted(b, a, sorter=sorter)]
array([0, 1, 4])

This returns the indices for values as they appear in a. For instance:

a = np.array([1, 2, 4])
b = np.array([4, 2, 3, 1])

>>> sorter = np.argsort(b)
>>> sorter[np.searchsorted(b, a, sorter=sorter)]
array([3, 1, 0]) # the other method would return [0, 1, 3]

How to get the values from a NumPy array using multiple indices

Try like this:

>>> arr = np.array([100.10, 200.42, 4.14, 89.00, 34.55, 1.12])
>>> arr[[1,4,5]]
array([ 200.42, 34.55, 1.12])

And for multidimensional arrays:

>>> arr = np.arange(9).reshape(3,3)
>>> arr
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
>>> arr[[0, 1, 1], [1, 0, 2]]
array([1, 3, 5])

Find index of multiple elements in numpy array

you may try this:

In [378]: (a1[:, None] == a2).argmax(axis=0)
Out[378]: array([4, 5, 1, 2, 8], dtype=int64)

Getting the indices of several rows in a NumPy array at once

Given A and B, you can generate C using

In [25]: (B[:,None,:] == A).all(axis=-1).argmax(axis=0)
Out[25]: array([0, 1, 0, 2, 1, 2, 2])

Note that this assumes that every row of B is in A. (Otherwise, argmax could return bogus indices where the equality is False.)


Note that if you had NumPy version 1.13 or newer, then
you could use np.unique to generate both B and C at the same time:

In [33]: np.unique(A, axis=0, return_inverse=True)
Out[33]:
(array([[1, 2, 3],
[2, 2, 2],
[2, 3, 3]]), array([0, 1, 0, 2, 1, 2, 2]))

Note that Divakar's solution (using np.void) is far faster, particularly if A has many rows:

A = np.random.randint(10, size=(1000, 3))
B, C = np.unique(A, axis=0, return_inverse=True)

In [44]: %%timeit
....: A1D, B1D = view1D(A, B)
....: sidx = B1D.argsort()
....: out = argsort_unique(sidx)[np.searchsorted(B1D, A1D, sorter=sidx)]
....:
1000 loops, best of 3: 271 µs per loop

In [45]: %timeit (B[:,None,:] == A).all(axis=-1).argmax(axis=0)
100 loops, best of 3: 15.5 ms per loop

Numpy: Indices of multiple values

With numpy, you can vectorize this by first finding the indices of elements that are in indList and then setting them to be zero.

A = np.array([[1, 6, 6],
[9, 7, 7],
[10 ,2 ,2]])

A[np.where(np.isin(A, [10,1]))] = 0

This gives

A = [[0 6 6]
[9 7 7]
[0 2 2]]

Retrieve indexes of multiple values with Numpy in a vectorization way

Here's one approach with np.searchsorted -

def find_indexes(ar, searched_values, invalid_val=-1):
sidx = ar.argsort()
pidx = np.searchsorted(ar, searched_values, sorter=sidx)
pidx[pidx==len(ar)] = 0
idx = sidx[pidx]
idx[ar[idx] != searched_values] = invalid_val
return idx

Sample run -

In [29]: find_indexes(mynumpy, searched_values, invalid_val=-1)
Out[29]: array([ 4, -1, 1, 5, 8])

For a generic invalid value specifier, we could use np.where -

def find_indexes_v2(ar, searched_values, invalid_val=-1):
sidx = ar.argsort()
pidx = np.searchsorted(ar, searched_values, sorter=sidx)
pidx[pidx==len(ar)] = 0
idx = sidx[pidx]
return np.where(ar[idx] == searched_values, idx, invalid_val)

Sample run -

In [35]: find_indexes_v2(mynumpy, searched_values, invalid_val=None)
Out[35]: array([4, None, 1, 5, 8], dtype=object)

# For list output
In [36]: find_indexes_v2(mynumpy, searched_values, invalid_val=None).tolist()
Out[36]: [4, None, 1, 5, 8]


Related Topics



Leave a reply



Submit