Matrix Multiplication with np.matmul and @
Multiply matrices correctly with np.matmul and the @ operator, distinguish element-wise * from true matrix multiplication.
Matrix Multiplication with np.matmul and @ is a free Pandas & NumPy Academy lesson on CoddyKit — lesson 1 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Pandas & NumPy Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Why Matrix Multiplication Matters
Matrix multiplication is at the heart of data science and machine learning. It underpins neural networks, dimensionality reduction, and linear transformations. In Python, NumPy gives you two clean ways to multiply matrices: the np.matmul() function and the @ operator introduced in Python 3.5. Both are fast, vectorized, and far more efficient than nested Python loops.
The Rules of Matrix Multiplication
For two matrices A and B, the product A @ B is valid only when the number of columns in A equals the number of rows in B. If A is shape (m, n) and B is shape (n, k), the result is shape (m, k). This rule is called the inner-dimension constraint and applies regardless of which NumPy function you use.
import numpy as np
A = np.array([[1, 2], [3, 4]]) # shape (2, 2)
B = np.array([[5, 6], [7, 8]]) # shape (2, 2)
C = A @ B
print(C) # [[19 22] [43 50]]np.matmul vs the @ Operator
np.matmul(A, B) and A @ B produce identical results for 2-D arrays. The @ operator is simply syntactic sugar — it calls __matmul__ under the hood, which NumPy implements with the same C-level BLAS routine. Use @ in everyday code for readability; use np.matmul when you want to pass the function as a callable or handle edge cases explicitly.
import numpy as np
A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])
print(np.matmul(A, B)) # same as A @ B
print(A @ B) # same resultDistinguishing @ from * and np.dot
NumPy has three multiplication functions that are easy to confuse. A * B is element-wise multiplication (Hadamard product). np.dot(A, B) behaves like np.matmul for 2-D arrays but has different semantics for higher dimensions. A @ B is strictly matrix multiplication and follows the mathematical definition precisely — prefer it over np.dot for matrix work.
import numpy as np
A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])
print('element-wise:', A * B) # [[5 12] [21 32]]
print('matmul:', A @ B) # [[19 22] [43 50]]Matrix Multiplication Is Not Commutative
Unlike scalar multiplication, matrix multiplication is not commutative: A @ B generally differs from B @ A. The shapes may not even be compatible in both directions. This matters when writing transformations — the order of operations changes the result. Always keep track of which matrix is on the left versus the right.
import numpy as np
A = np.array([[1, 2], [3, 4]])
B = np.array([[0, 1], [1, 0]])
print('A @ B:', A @ B) # [[2 1] [4 3]]
print('B @ A:', B @ A) # [[3 4] [1 2]] -- different!Batched Matrix Multiplication
When your arrays have more than two dimensions, np.matmul and @ treat the extra leading dimensions as batch dimensions and multiply matrices in parallel. For example, an array of shape (32, 3, 4) multiplied by one of shape (32, 4, 5) produces a result of shape (32, 3, 5) — 32 independent 3×4 @ 4×5 multiplications at once. This is how deep learning frameworks process mini-batches efficiently.
import numpy as np
batch_A = np.random.rand(32, 3, 4)
batch_B = np.random.rand(32, 4, 5)
result = batch_A @ batch_B
print(result.shape) # (32, 3, 5)Matrix-Vector Multiplication
A common special case is multiplying a matrix by a vector. If A is shape (m, n) and v is a 1-D array of length n, then A @ v produces a 1-D array of length m. NumPy handles the shape alignment automatically — you do not need to reshape v into a column vector. This pattern appears everywhere: applying weights in linear regression, projecting features, and computing dot products for each row simultaneously.
import numpy as np
A = np.array([[1, 2, 3], [4, 5, 6]]) # (2, 3)
v = np.array([1, 0, -1]) # (3,)
print(A @ v) # [1-3, 4-6] = [-2, -2]Performance: @ vs Python Loops
NumPy matrix multiplication calls optimized BLAS/LAPACK routines and runs in compiled C code. A pure Python nested loop implementing the same operation is typically 100–1000× slower for large matrices. When you need repeated matrix products in a data pipeline — feature transformations, PCA projections, weight updates — always use @ or np.matmul and never implement the inner loop yourself.
import numpy as np, time
A = np.random.rand(500, 500)
B = np.random.rand(500, 500)
t0 = time.time()
C = A @ B
print(f'NumPy: {(time.time()-t0)*1000:.1f} ms') # single-digit msChaining Multiple Matrix Products
You can chain multiple @ operations in one expression: A @ B @ C evaluates left to right. NumPy does not optimize the multiplication order automatically (unlike MATLAB's mtimes), so if the matrices have very different sizes, the order can matter for speed. For three or more matrices consider using np.linalg.multi_dot([A, B, C]), which automatically selects the most efficient pairing.
import numpy as np
A = np.random.rand(100, 20)
B = np.random.rand(20, 50)
C = np.random.rand(50, 10)
result = np.linalg.multi_dot([A, B, C])
print(result.shape) # (100, 10)Common Shape Errors and How to Fix Them
The most common error with matrix multiplication is a shape mismatch: ValueError: matmul: Input operand 1 has a mismatch in its core dimension 0. The fix is to check shapes with A.shape and ensure the inner dimensions agree. If you have a row vector of shape (n,) that needs to be treated as a column vector (n, 1), use v.reshape(-1, 1). If you need the transpose, use A.T.
import numpy as np
A = np.ones((3, 4))
B = np.ones((3, 4)) # wrong -- inner dims 4 != 3
try:
A @ B
except ValueError as e:
print('Error:', e)
print('Fix:', (A @ B.T).shape) # (3, 3)Practical Example: Feature Transformation
A typical data science use case: you have a dataset X of shape (n_samples, n_features) and a weight matrix W of shape (n_features, n_outputs). The matrix product X @ W applies a linear transformation to every sample simultaneously, producing shape (n_samples, n_outputs). This is the core computation of a linear layer in a neural network and of linear regression prediction.
import numpy as np
n_samples, n_features, n_outputs = 200, 10, 3
X = np.random.rand(n_samples, n_features)
W = np.random.rand(n_features, n_outputs)
b = np.zeros(n_outputs)
predictions = X @ W + b # shape (200, 3)
print(predictions.shape)Quick Check
Test your understanding of NumPy matrix multiplication.
Lesson Recap
In this lesson you learned: np.matmul and @ implement true matrix multiplication (not element-wise), the inner dimensions of the two matrices must match, and @ supports batched multiplication over leading dimensions. Next up we explore determinants, inverses, and transposes — the operations that tell you whether a matrix can be 'undone'.
Frequently asked questions
Is the “Matrix Multiplication with np.matmul and @” lesson free?
Yes — the full text of “Matrix Multiplication with np.matmul and @” is free to read here on the web, and the Pandas & NumPy Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Pandas & NumPy Academy course, upgrade to CoddyKit PRO.
What will I learn in “Matrix Multiplication with np.matmul and @”?
Multiply matrices correctly with np.matmul and the @ operator, distinguish element-wise * from true matrix multiplication. You practise Pandas & NumPy Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Pandas & NumPy Academy?
No prior experience is required. Pandas & NumPy Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 1 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Matrix Multiplication with np.matmul and @” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Pandas & NumPy Academy lesson?
Yes. Every Pandas & NumPy Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Matrix Multiplication with np.matmul and @
- Determinants, Inverses, and Transposes
- Solving Linear Systems
- Eigenvalues and SVD Overview