3

I have a tensor A such that A.shape = (32, 19, 2) and a binary matrix B such that B.shape = (32, 19). Is there a one-line operation I can perform to get a matrix C, where C.shape = (32, 19) and C(i,j) = A[i, j, B[i,j]]?

Essentially, I want to use B as an indexing matrix, where if B[i,j] = 1 I take A[i,j,1] to form C(i,j).

3 Answers 3

2

np.where to the rescue. It's the same principle as mtrw's answer:

In [344]: A=np.arange(4*3*2).reshape(4,3,2)

In [345]: B=np.zeros((4,3),dtype=int)

In [346]: B[[0,1,1,2,3],[0,0,1,2,2]]=1

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

In [348]: np.where(B,A[:,:,1],A[:,:,0])
Out[348]: 
array([[ 1,  2,  4],
       [ 7,  9, 10],
       [12, 14, 17],
       [18, 20, 23]])

np.choose can be used if the last dimension is larger than 2 (but smaller than 32). (choose operates on a list or the 1st dimension, hence the rollaxis.

In [360]: np.choose(B,np.rollaxis(A,2))
Out[360]: 
array([[ 1,  2,  4],
       [ 7,  9, 10],
       [12, 14, 17],
       [18, 20, 23]])

B can also be used directly as an index. The trick is to specify the other dimensions in a way that broadcasts to the same shape.

In [373]: A[np.arange(A.shape[0])[:,None], np.arange(A.shape[1])[None,:], B]
Out[373]: 
array([[ 1,  2,  4],
       [ 7,  9, 10],
       [12, 14, 17],
       [18, 20, 23]])

This last approach can be modified to work when B does not match the 1st 2 dimensions of A.

np.ix_ may simplify this indexing

I, J = np.ix_(np.arange(4),np.arange(3))
A[I, J, B]
Sign up to request clarification or add additional context in comments.

Comments

0

You can do it using list comprehension:

C = np.array([[A[i, j, B[i, j]] for j in range(A.shape[1])] for i in range(A.shape[0])])

Comments

0

C = A[:,:,0]*(B==0) + A[:,:,1]*(B==1) should work. You can generalize this as np.sum([A[:,:,k]*(B==k) for k in np.arange(A.shape[-1])], axis=0) if you need to index more planes.

Comments

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.