3

I'm trying to take a list of elements from an 2D numpy array with given list of coordinates and I want to avoid using loop. I saw that np.take works with 1D array but I can't make it work with 2D arrays.

Example:

a = np.array([[1,2,3], [4,5,6]])
print(a)
# [[1 2 3]
#  [4 5 6]]

np.take(a, [[1,2]])
# gives [2, 3] but I want just [6]

I want to avoid loop because I think that will be slower (I need speed). But if you can persuade me that a loop is as fast as an existing numpy function solution, then I can go for it.

4
  • Does this do what you want? a[1].take([2]) Ignoring the index error in your question... this returns array([6]) Commented Feb 12, 2020 at 15:47
  • Then, if I have a list of coordinates, I need to do [a[i].take(j) for i,j in coords], will that be slower if there's a built-in numpy function that can potentially do it? Commented Feb 12, 2020 at 15:51
  • How your list of coordinates looks like? Is it like ‘[[y0, x0], [y1, x1], ...]‘ ? Commented Feb 12, 2020 at 16:03
  • 1
    np.take(a, [[-1]]) but why not just use a slice... a[1, 2] Commented Feb 12, 2020 at 16:27

2 Answers 2

3

If I understand it correctly, you have a list of coordinates like this:

coords = [[y0, x0], [y1, x1], ...]

To get the values of array a at these coordinates you need:

a[[y0, y1, ...], [x0, x1, ...]]

So a[coords] will not work. One way to do it is:

Y = [c[0] for c in coords]
X = [c[1] for c in coords]

or

Y = np.transpose(coords)[0]
X = np.transpose(coords)[1]

Then

a[Y, X]
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for the answer! Exactly what I wanted. I just tested out and it seems like the speed is very similar to np.take method along with list comprehension. But still kudos for you!
1

Does fancy indexing do what you want? np.take seems to flatten the array before operating.

import numpy as np

a = np.arange(1, 10).reshape(3,3)

a
# array([[1, 2, 3],
#        [4, 5, 6],
#        [7, 8, 9]])

rows = [ 1,1,2,0]
cols = [ 0,1,1,2]

# Use the indices to access items in a
a[rows, cols]
# array([4, 5, 8, 3])

a[1,0], a[1,1], a[2,1], a[0,2]
# (4, 5, 8, 3)

3 Comments

How is this different from what I wrote? ;)
It was written in parallel. I only saw yours after I posted.
Thank you for the answer! Exactly what I wanted. I just tested out and it seems like the speed is very similar to np.take method along with list comprehension. Since Andreas K. answered slight faster than you, so I will accept his answer, but still kudos for you!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.