7

For example, I have two numpy arrays,

A = np.array(
  [[0,1], 
   [2,3], 
   [4,5]])
B = np.array(
  [[1],
   [0],
   [1]], dtype='int')

and I want to extract one element from each row of A, and that element is indexed by B, so I want the following results:

C = np.array(
  [[1],
   [2],
   [5]])

I tried A[:, B.ravel()], but it'll broadcast B, not what I want. Also looked into np.take, seems not the right solution to my problem.

However, I could use np.choose by transposing A,

np.choose(B.ravel(), A.T)

but any other better solution?

4
  • 2
    Possible duplicate: stackoverflow.com/q/37878946/190597 Commented Jun 18, 2016 at 14:03
  • 1
    @unutbu Well sort of different here, as we are selecting one element per row as opposed to multiple elements per row in the linked previous question. Commented Jun 18, 2016 at 14:06
  • @Divakar: If the OP wants the 2D array, C, your answer on the linked page gives the desired result exactly. Commented Jun 18, 2016 at 14:15
  • 1
    @unutbu, the answer you linked use np.take, and I don't think it could fix my problem? Commented Jun 19, 2016 at 0:21

2 Answers 2

7

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])
Sign up to request clarification or add additional context in comments.

2 Comments

so no broadcasting at all?
Well you don't need broadcasting here, if I got the expected output correctly from the question. We are basically using integers at each dim, to select elements. We have the 2nd dim indices from B, so we just needed to create the corresponding ones for the first dim using np.arange. Hope that made sense!
-1
C = np.array([A[i][j] for i,j in enumerate(B)])

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.