Using an Numpy Array as Indices of the 2Nd Dim of Another Array

using an numpy array as indices of the 2nd dim of another array?

You can use NumPy's purely integer array indexing -

A[np.arange(A.shape[0]),B.ravel()]

Sample run -

In [57]: A
Out[57]:
array([[0, 1],
[2, 3],
[4, 5]])

In [58]: B
Out[58]:
array([[1],
[0],
[1]])

In [59]: A[np.arange(A.shape[0]),B.ravel()]
Out[59]: array([1, 2, 5])

Please note that if B is a 1D array or a list of such column indices, you could simply skip the flattening operation with .ravel().

Sample run -

In [186]: A
Out[186]:
array([[0, 1],
[2, 3],
[4, 5]])

In [187]: B
Out[187]: [1, 0, 1]

In [188]: A[np.arange(A.shape[0]),B]
Out[188]: array([1, 2, 5])

Splitting numpy multidimensional array based on indices stored in another array or list

You can use np.arange for indexing the first dimension:

test = arr[np.arange(arr.shape[0]),indices,...]

or just the python range function:

test = arr[range(arr.shape[0]),indices,...]

In numpy, how do I use a list of indices to slice from the second dimension of a 2D array?

Use this:

>>> index = np.array([1, 3, 4])
>>> foo[range(foo.shape[0]), index]
array([101, 203, 304])

Index a numpy array with another array

Just use a tuple:

>>> A[(3, 1)]
8
>>> A[tuple(ind)]
8

The A[] actually calls the special method __getitem__:

>>> A.__getitem__((3, 1))
8

and using a comma creates a tuple:

>>> 3, 1
(3, 1)

Putting these two basic Python principles together solves your problem.

You can store your index in a tuple in the first place, if you don't need NumPy array features for it.

Get indices of element of one array using indices in another array

I have a solution similar to that of Andras based on np.argmax and np.arange. Instead of "indexing the index" I propose to add a piecewise offset to the result of np.argmax:

import numpy as np
a = np.array([[[7, 9],
[19, 18]],
[[24, 5],
[18, 11]]])
off = np.arange(0, a.size, a.shape[2]).reshape(a.shape[0], a.shape[1])
>>> off
array([[0, 2],
[4, 6]])

This results in:

>>> a.argmax(-1) + off
array([[1, 2],
[4, 6]])

Or as a one-liner:

>>> a.argmax(-1) + np.arange(0, a.size, a.shape[2]).reshape(a.shape[0], a.shape[1])
array([[1, 2],
[4, 6]])

Indexing one array by another in numpy

EDIT: np.take_along_axis is a builtin function for this use case implemented since numpy 1.15. See @hpaulj 's answer below for how to use it.


You can use NumPy's advanced indexing -

A[np.arange(A.shape[0])[:,None],B]

One can also use linear indexing -

m,n = A.shape
out = np.take(A,B + n*np.arange(m)[:,None])

Sample run -

In [40]: A
Out[40]:
array([[2, 4, 5, 3],
[1, 6, 8, 9],
[8, 7, 0, 2]])

In [41]: B
Out[41]:
array([[0, 0, 1, 2],
[0, 3, 2, 1],
[3, 2, 1, 0]])

In [42]: A[np.arange(A.shape[0])[:,None],B]
Out[42]:
array([[2, 2, 4, 5],
[1, 9, 8, 6],
[2, 0, 7, 8]])

In [43]: m,n = A.shape

In [44]: np.take(A,B + n*np.arange(m)[:,None])
Out[44]:
array([[2, 2, 4, 5],
[1, 9, 8, 6],
[2, 0, 7, 8]])

how to find indices of a 2d numpy array occuring in another 2d array

What you want is:

sum([row in small_array for row in big_array])

Example:

import numpy as np
big_array = np.array([[1., 2., 1.2], [5., 3., 0.12], [-1., 14., 0.], [-9., 0., 13.]])
small_array= np.array([[5., 3., 0.12], [-1., 14., 0.]])

result = sum([row in small_array for row in big_array])
print(result)

2


Edit (after clarifications):

A pythonic solution:

[i for i, brow in enumerate(big_array) for srow in small_array if all(srow == brow)]

Example:

big_array = np.array([[1., 2., 1.2], [5., 3., 0.12], [-1., 14., 0.], [-9., 0., 13.]])
small_array= np.array([[5., 3., 0.12], [-1., 14., 0.]])

result = [i for i, brow in enumerate(big_array) for srow in small_array if all(srow == brow)]

print(result)

[1, 2]

Note: you could probably do something better with np.where, if you have huge arrays you should look it up

Find indices of numpy array based on values in another numpy array

Taking into account the proposed options on the comments, and adding an extra option with numpy's in1d option:

>>> import numpy as np
>>> summed_rows = np.random.randint(low=1, high=14, size=9999)
>>> common_sums = np.array([7,10,13])
>>> ind_1 = (summed_rows==common_sums[:,None]).any(0).nonzero()[0] # Option of @Brenlla
>>> ind_2 = np.where(summed_rows == common_sums[:, None])[1] # Option of @Ravi Sharma
>>> ind_3 = np.arange(summed_rows.shape[0])[np.in1d(summed_rows, common_sums)]
>>> ind_4 = np.where(np.in1d(summed_rows, common_sums))[0]
>>> ind_5 = np.where(np.isin(summed_rows, common_sums))[0] # Option of @jdehesa

>>> np.array_equal(np.sort(ind_1), np.sort(ind_2))
True
>>> np.array_equal(np.sort(ind_1), np.sort(ind_3))
True
>>> np.array_equal(np.sort(ind_1), np.sort(ind_4))
True
>>> np.array_equal(np.sort(ind_1), np.sort(ind_5))
True

If you time it, you can see that all of them are quite similar, but @Brenlla's option is the fastest one

python -m timeit -s 'import numpy as np; np.random.seed(0); a = np.random.randint(low=1, high=14, size=9999); b = np.array([7,10,13])' 'ind_1 = (a==b[:,None]).any(0).nonzero()[0]'
10000 loops, best of 3: 52.7 usec per loop

python -m timeit -s 'import numpy as np; np.random.seed(0); a = np.random.randint(low=1, high=14, size=9999); b = np.array([7,10,13])' 'ind_2 = np.where(a == b[:, None])[1]'
10000 loops, best of 3: 191 usec per loop

python -m timeit -s 'import numpy as np; np.random.seed(0); a = np.random.randint(low=1, high=14, size=9999); b = np.array([7,10,13])' 'ind_3 = np.arange(a.shape[0])[np.in1d(a, b)]'
10000 loops, best of 3: 103 usec per loop

python -m timeit -s 'import numpy as np; np.random.seed(0); a = np.random.randint(low=1, high=14, size=9999); b = np.array([7,10,13])' 'ind_4 = np.where(np.in1d(a, b))[0]'
10000 loops, best of 3: 63 usec per loo

python -m timeit -s 'import numpy as np; np.random.seed(0); a = np.random.randint(low=1, high=14, size=9999); b = np.array([7,10,13])' 'ind_5 = np.where(np.isin(a, b))[0]'
10000 loops, best of 3: 67.1 usec per loop

Indexing numpy array with another numpy array

According the NumPy tutorial, the correct way to do it is:

a[tuple(b)]


Related Topics



Leave a reply



Submit