It seems you are trying to lose the last two axes of the first array against the only two axes of the second weight array with that matrix-multiplication. We could translate that idea into NumPy code with np.tensordot and assuming arr1 and arr2 as the input arrays respectively, like so -

np.tensordot(arr1,arr2,axes=([1,2],[0,1]))

Another simpler way to put into NumPy code would be with np.einsum, like so -

np.einsum('ijk,jk',arr1,arr2)
Answer from Divakar on Stack Overflow
🌐
Reddit
reddit.com › r/learnpython › how do i multiply 3d arrays by 2d arrays?
r/learnpython on Reddit: How do I multiply 3D arrays by 2D arrays?
March 5, 2019 -

I currently have a loop where I have a 3D array A[2x2x1000] and a 2D array B[2x2]. I want to multiply A by B for every value in the 3rd dimension without using a loop.

My current loop does the job but it runs slowly.

for i in range(1000):
    C[:,:,i] = A[:,:,i]*B

I've come across np.einsum, np.matmul and np.tensordot but I'm not completely sure how these work and how to use them.

Any help would be much appreciated.

Matrix multiplication of 3d arrays Nov 5, 2024
r/learnpython
2y ago
How to manipulate 2D arrays? Oct 29, 2024
r/learnpython
2y ago
More results from reddit.com
Discussions

python - Numpy multiply 3d matrix by 2d matrix - Stack Overflow
We can reshape A to 2D after swapping axes, use 2D matrix multiplication with np.dot and reshape and swap axes to maybe gain marginal performance boost. More on stackoverflow.com
🌐 stackoverflow.com
June 11, 2018
python - Numpy - multiple 3d array with a 2d array - Stack Overflow
I'm trying the following: Given a matrix A (x, y ,3) and another matrix B (3, 3), I would like to return a (x, y, 3) matrix in which the 3rd dimension of A is multiplied by the values of B (simila... More on stackoverflow.com
🌐 stackoverflow.com
python - How to matrix-multiply a 2D numpy array with a 3D array to give a 3D array? - Stack Overflow
The problem is that numpy views multidimensional arrays as stacks of matrices, and always the last two dimensions are assumed to be the linear space dimensions. This means that the dot product will not work by collapsing the first dimension of your 3d array. Instead the simplest thing you can do is to reshape your 3d array into a 2d one, doing the matrix multiplication... More on stackoverflow.com
🌐 stackoverflow.com
How can arrays with different dimensions be multiplied? - Python - Data Science Dojo Discussions
I encountered an error while attempting to multiply two numpy arrays with different dimensions in my data science project. Could anyone kindly share insights on the correct ways to multiply matrices with disparate dimensions in the context of numpy arrays? Your assistance with a code snippet ... More on discuss.datasciencedojo.com
🌐 discuss.datasciencedojo.com
3
0
February 28, 2023
🌐
GeeksforGeeks
geeksforgeeks.org › numpy-3d-matrix-multiplication
NumPy - 3D matrix multiplication - GeeksforGeeks
November 2, 2023 - A 3D matrix is nothing but a collection ... So, matrix multiplication of 3D matrices involves multiple multiplications of 2D matrices, which eventually boils down to a dot product between their row/column vectors....
🌐
YouTube
youtube.com › codemore
How do I multiply a 3D matrix and 2D matrix using numpy in Python - YouTube
Download this code from https://codegive.com Certainly! Multiplying a 3D matrix and a 2D matrix using NumPy in Python involves using the numpy.dot() function...
Published: November 21, 2023
Views: 113
🌐
DigitalOcean
digitalocean.com › community › tutorials › numpy-matrix-multiplication
NumPy Matrix Multiplication: Methods and Examples | DigitalOcean
August 4, 2022 - Perform matrix multiplication in NumPy using dot(), matmul(), and @ operator. Complete guide with examples for 2D, 3D arrays and performance tips.
🌐
Blogger
debmoran.blogspot.com › home › multiply › numpy
Numpy Multiply 3d Array By 2d Array - Deb Moran's Multiplying Matrices
July 30, 2021 - What you can do there is reshape your 2D array B such that it is a 3D array with an inner dimension of length 1. A handful of simple operations. In order to perform matrix multiplication of 2-dimensional arrays we can use the numpy dot function.
Find elsewhere
🌐
Javatpoint
javatpoint.com › numpy-3d-matrix-multiplication
Numpy-3d Matrix Multiplication - Javatpoint
Numpy-3d Matrix Multiplication with tutorial, tkinter, button, overview, canvas, frame, environment set-up, first python program, etc.
🌐
NumPy
numpy.org › doc › stable › reference › generated › numpy.matmul.html
numpy.matmul — NumPy v2.5 Manual
Vector-matrix product for stacks of vectors and matrices. ... Sum products over arbitrary axes. ... Einstein summation convention. ... The behavior depends on the arguments in the following way. If both arguments are 2-D they are multiplied like conventional matrices.
Top answer
1 of 4
3

The problem is that numpy views multidimensional arrays as stacks of matrices, and always the last two dimensions are assumed to be the linear space dimensions. This means that the dot product will not work by collapsing the first dimension of your 3d array.

Instead the simplest thing you can do is to reshape your 3d array into a 2d one, doing the matrix multiplication, and reshaping back into a 3d array. This will also make use of optimised BLAS code which is one of the great advantages of numpy.

import numpy as np 

S_pinv = np.random.rand(3, 4)
images = np.random.rand(4, 5, 6)

# error: 
# (S_pinv @ images).shape 
res_shape = S_pinv.shape[:1] + images.shape[1:]  # (3, 5, 6) 
res = (S_pinv @ images.reshape(images.shape[0], -1)).reshape(res_shape)
print(res.shape)  # (3, 5, 6)

So instead of (3,n) x (n,h,w) we do (3,n) x (n, h*w) -> (3, h*w) which we reshape back to (3, h, w). Reshaping is free, because this doesn't mean any actual manipulation of data in memory (only a reinterpretation of the single block of memory that underlies the array), and as I said proper matrix products are highly optimized in numpy.


Since you asked for a more intuitive way, here's an alternative making use of numpy.einsum. It will probably be slower, but it's very transparent if you get a little bit used to its notation:

res_einsum = np.einsum('tn,nhw -> thw', S_pinv, images)
print(np.array_equal(res, res_einsum))  # True

This notation names each of the dimensions of the input arrays: for S_pinv the first and second dimensions are named t and n, respectively, and similarly n, h and w for images. The output is set to have dimensions thw which means that any remaining dimensions that are not present in the output shape will be summed along after multiplying the input arrays. This is exactly what you need.


As you noted in a comment, you could also transpose your arrays so that np.dot finds the right dimensions in the right place. But this will also be slow because this might lead to copies in memory, or at least suboptimal looping over your arrays.

I made a quick timing comparison using the following defininitions:

def reshaped(S_pinv, images): 
    res_shape = S_pinv.shape[:1] + images.shape[1:] 
    return (S_pinv @ images.reshape(images.shape[0], -1)).reshape(res_shape)

def einsummed(S_pinv, images): 
    return np.einsum('tn,nhw -> thw', S_pinv, images) 

def transposed(S_pinv, images): 
    return (S_pinv @ images.transpose(2, 0, 1)).transpose(1, 2, 0)          

And here's the timing test using IPython's built-in %timeit magic, and some more realistic array sizes:

>>> S_pinv = np.random.rand(3, 100) 
... images = np.random.rand(100, 200, 300) 
... args = S_pinv, images 
... %timeit reshaped(*args) 
... %timeit einsummed(*args) 
... %timeit transposed(*args)                                          
5.92 ms ± 460 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
15.9 ms ± 190 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
44.5 ms ± 329 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
2 of 4
0

answer is np.swapaxes

import numpy as np

q= np.random.random([2, 5,5])
q.shape

w = np.random.random([3,2])
w.shape

w@q

and we have ValueError but

import numpy as np

q= np.random.random([5, 2,5])
q.shape

w = np.random.random([3,2])
w.shape

res = (w@q).swapaxes(0,1)
res.shape # =[3, 5, 5]
🌐
NumPy
numpy.org › doc › stable › reference › generated › numpy.multiply.html
numpy.multiply — NumPy v2.5 Manual
Multiply arguments element-wise · Input arrays to be multiplied. If x1.shape != x2.shape, they must be broadcastable to a common shape (which becomes the shape of the output)
🌐
Educative
educative.io › blog › numpy-matrix-multiplication
NumPy matrix multiplication: Get started in 5 minutes
April 30, 2026 - Try one of our courses on Python programming fundamentals: ... The matmul() function gives us the matrix product of two 2-d arrays. With this method, we can’t use scalar values for our input.
🌐
YouTube
youtube.com › watch
Understanding Numpy Matmul in 3D through Examples - YouTube
Here I take you through many examples of Numpy matrix multiplication with combinations of 3D, 2D, and 1D arrays. By the end of the video, you'll have a deep ...
Published: August 23, 2023
🌐
Data Science Dojo
discuss.datasciencedojo.com › python
How can arrays with different dimensions be multiplied? - Python - Data Science Dojo Discussions
February 28, 2023 - Yes, you can multiply arrays of different dimensions using NumPy’s .reshape() method. It will first reshape the arrays to match their dimensions and then apply multiplication. A sample code is provided below for your understanding.
Top answer
1 of 2
8

For array of dimension 3 (or, a rank-3 tensor) that you have, you can use np.einsum doc for more complex matrix multiplications. In your particular case, you can use the following

>>> import numpy as np
>>> x = np.random.randint(0, 3, (3, 3, 3))  # shape (3, 3, 3)
>>> y = np.random.randint(0, 3, (3, 3, 3))  # shape (3, 3, 3)
>>> np.einsum('ijk,ikl->ijl', x, y)  # still shape (3, 3, 3)

In particular, the einsum expression 'ijk,ikl->ijl' means for each ith matrix, do a regular matrix multiplication jk,kl->jl and put the result in the ith entry in the resulting tensor (ndarray). A more general form of this process could be

np.einsum('...jk,...kl->...jl', x, y)

where you can have arbitrary number of dimensions in front of each tensor (ndarray) that you have.

See the following for a complete example:

>>> import numpy as np
>>> x = np.random.randint(0, 3, (3, 3, 3))  # shape (3, 3, 3)
>>> x
array([[[0, 0, 1],
        [2, 2, 1],
        [2, 1, 1]],

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

       [[2, 2, 2],
        [1, 1, 2],
        [0, 2, 2]]])
>>> y = np.random.randint(0, 3, (3, 3, 3))  # shape (3, 3, 3)
>>> y
array([[[0, 0, 1],
        [2, 1, 0],
        [0, 0, 2]],

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

       [[0, 2, 1],
        [0, 1, 0],
        [0, 2, 1]]])
>>> np.einsum('ijk,ikl->ijl', x, y)
array([[[ 0,  0,  2],
        [ 4,  2,  4],
        [ 2,  1,  4]],

       [[ 6,  8,  2],
        [ 8,  6,  3],
        [10,  8,  4]],

       [[ 0, 10,  4],
        [ 0,  7,  3],
        [ 0,  6,  2]]])
>>> np.einsum('...ij,...jk->...ik', x, y)
array([[[ 0,  0,  2],
        [ 4,  2,  4],
        [ 2,  1,  4]],

       [[ 6,  8,  2],
        [ 8,  6,  3],
        [10,  8,  4]],

       [[ 0, 10,  4],
        [ 0,  7,  3],
        [ 0,  6,  2]]])
2 of 2
1

np.matmul(A,B) works just fine. What error(s) did you get?

In [263]: A,B = np.arange(24).reshape(2,3,4), np.arange(8).reshape(2,4,1)

The einsum solution:

In [264]: np.einsum('ijk,ikl->ijl',A,B)
Out[264]: 
array([[[ 14],
        [ 38],
        [ 62]],

       [[302],
        [390],
        [478]]])
In [265]: _.shape
Out[265]: (2, 3, 1)

The matmul solution:

In [266]: A@B
Out[266]: 
array([[[ 14],
        [ 38],
        [ 62]],

       [[302],
        [390],
        [478]]])

Your loop:

In [267]: [np.matmul(a, b) for a, b in zip(A, B)]
Out[267]: 
[array([[14],
        [38],
        [62]]),
 array([[302],
        [390],
        [478]])]

matmuldocs:

If either argument is N-D, N > 2, it is treated as a stack of
matrices residing in the last two indexes and broadcast accordingly.
🌐
TutorialsPoint
tutorialspoint.com › numpy › numpy_array_multiplication.htm
NumPy - Array Multiplication
The np.matmul() function can handle arrays with more than two dimensions by performing matrix multiplication on the last two dimensions of the input arrays, with any preceding dimensions being broadcasted as needed − · import numpy as np ...
🌐
NumPy
numpy.org › doc › 2.1 › reference › generated › numpy.multiply.html
numpy.multiply — NumPy v2.1 Manual
>>> x1 = np.arange(9.0).reshape((3, 3)) >>> x2 = np.arange(3.0) >>> np.multiply(x1, x2) array([[ 0., 1., 4.], [ 0., 4., 10.], [ 0., 7., 16.]])