0

I have a 3D numpy array and I want to multiply it with a 2D array, The 3D looks like follows:

C= np.zeros((3, 2, 2))
C[0][0] = [0,0]
C[0][1] = [0,1]
C[1][0] = [1,0]
C[1][1] = [1,1]
C[2][0] = [1,2]
C[2][1] = [2,1]

The 2D array looks like:

V = np.zeros((3,2)) 
V[0][0] = 1
V[0][1] = 2
V[1][0] = 1
V[1][1] = 3
V[2][0] = 4 
V[2][1] = 5

The result R is to be a 2X2 2D array(4 elements in total) R=[[5,8],[13,10]] where:

R[0] = V[0][0]*C[0][0]+V[1][0]*C[1][0]+V[2][0]*C[2][0] = [5,8] (first row of R)

R[1] = V[0][1]*C[0][1]+V[1][1]*C[1][1]+V[2][1]*C[2][1] = [13,10] (second row of R)

This is just an example, How Can I get R using numpy matrix multiplication operation with V and C (with no for loop!). Please help!

Sorry I made some edit later, the comment showed an old example, it should be good now

1
  • Comments are not for extended discussion; this conversation has been moved to chat. Commented Mar 23, 2022 at 5:43

2 Answers 2

3

Your example is confusing. Why do you say your expected result is [[1, 0], [5, 10]] but in your example you also say R should be [[5, 8], [13, 10]]?

I hope this was just a typo on your part because it's not clear from your example how you'd get from one to the other.

In any case:

(V.T * C.T).sum(axis=2).T

Output:

array([[ 5.,  8.],
       [13., 10.]])
Sign up to request clarification or add additional context in comments.

1 Comment

he was trying to get me to understand what he was trying to do ... I probably made him make it harder to understand overall (this is a great answer)
3
In [20]: C          # (3,2,2)
Out[20]: 
array([[[0, 0],
        [0, 1]],

       [[1, 0],
        [1, 1]],

       [[1, 2],
        [2, 1]]])
In [21]: V         # (3,2)
Out[21]: 
array([[1., 2.],
       [1., 3.],
       [4., 5.]])

Expand V to (3,2,1). This broadcasts with C to produce a (3,2,2):

In [22]: C * V[:,:,None]
Out[22]: 
array([[[ 0.,  0.],
        [ 0.,  2.]],

       [[ 1.,  0.],
        [ 3.,  3.]],

       [[ 4.,  8.],
        [10.,  5.]]])

and sum on the first axis to make (2,2) result:

In [23]: (C * V[:,:,None]).sum(axis=0)
Out[23]: 
array([[ 5.,  8.],
       [13., 10.]])

This answer cleans up @ddjohns answer; he did the hard work.

The sum-of-products can be expressed with einsum as:

In [24]: np.einsum('ijk,ij->jk',C,V)
Out[24]: 
array([[ 5.,  8.],
       [13., 10.]])

Reordering the axes, we can express it as a more conventional sum-of-products:

In [25]: np.einsum('jki,ji->jk',C.transpose(1,2,0),V.transpose(1,0))
Out[25]: 
array([[ 5.,  8.],
       [13., 10.]])

And use that to cast it as a matmul:

In [28]: (C.transpose(1,2,0)@V.transpose(1,0)[:,:,None]).squeeze(2)
Out[28]: 
array([[ 5.,  8.],
       [13., 10.]])

[28] is probably fastest, but [23] may be easier to understand.

1 Comment

I wanted to try finding a better way than having to use three transposes, but it was late and I wanted to go to bed :D This is a great answer.

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.