2

As the title say, given a 2d numpy array, for instance

a = np.array([[2,3,4,5],[12,4,5,7],[14,2,5,6],[12,3,4,6]])
idx = np.array([[0,2],[2,3],[1,3],[1,3]])

I want to select the first and third elements, 2, 4 from the first row, etc. So the final answer should be

ans = [[2,4],
       [5,7],
       [2,6],
       [3,6]]

I have tried both np.choose and np.take but I believe np.take flattens out the array, and np.choose doesn't look like what I expected.

Any idea would be appreciated! Many thanks!

1
  • When you are working with numpy, I would strongly suggest to avoid looping and take advantage of array operations. That is what numpy is strong at. Please check my answer for a vectorized solution without a need for any loops to your question. Commented May 12, 2020 at 2:19

3 Answers 3

3

You can use advance indexing in numpy:

a[np.indices(idx.shape)[0], idx]

np.indices(idx.shape)[0] creates the corresponding row indices for your column indices in idx and together, they form advance indexing.

output:

[[2 4]
 [5 7]
 [2 6]
 [3 6]]
Sign up to request clarification or add additional context in comments.

1 Comment

I completely forgot about np.indices. Very nice!
3

using List comprehension, you can loop over the 2 numpy array and create a new list that have the desired output. Later, you take each 2 elements and add them to a numpy array, this can be achieved using the reshape function:

aa = [a[index][x] for index, value in enumerate(idx) for x in value]
# aa = [2, 4, 5, 7, 2, 6, 3, 6]
aa = np.reshape(aa, (-1, 2))
print(aa)
# output 
[[2 4]
 [5 7]
 [2 6]
 [3 6]]

Comments

1

You could define some complex function that turns your idx into slices, but I think it would be much easier to access the array via list comprehension and enumerate, and then turn the list into an array. Like this:

a = np.array([[2,3,4,5],[12,4,5,7],[14,2,5,6],[12,3,4,6]])
idx = np.array([[0,2],[2,3],[1,3],[1,3]])

np.array([a[row,elems] for row,elems in enumerate(idx)])

result:

array([[2, 4],
       [5, 7],
       [2, 6],
       [3, 6]])

1 Comment

I guess you are right. I can do some tricks with numpy apply but list comprehension should be the more straightforward.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.