For two 2D arrays, matmul() requires the number of columns in a to match the number of rows in b, and computes the standard matrix product, where each output element is the dot product of a row from a and a column from b. Unlike np.dot(), matmul() treats arrays with more than 2 dimensions as a batch of matrices stacked along the leading dimensions, broadcasting and multiplying corresponding matrix pairs — a well-defined, predictable rule that makes matmul(), or the equivalent @ operator, the recommended choice over np.dot() for anything beyond plain vectors.
1Understanding np.matmul()
For two 2D arrays, matmul() requires the number of columns in a to match the number of rows in b, and computes the standard matrix product, where each output element is the dot product of a row from a and a column from b. Unlike np.dot(), matmul() treats arrays with more than 2 dimensions as a batch of matrices stacked along the leading dimensions, broadcasting and multiplying corresponding matrix pairs — a well-defined, predictable rule that makes matmul(), or the equivalent @ operator, the recommended choice over np.dot() for anything beyond plain vectors.
Use @, which calls np.matmul() internally, as your default for matrix multiplication in NumPy code — it reads cleanly, matches standard linear algebra conventions, and handles batched 3D+ matrix multiplication predictably, unlike np.dot().
import numpy as np
A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])
print(A @ B)2Practical Example
Here is a real-world application of np.matmul() showing how it is used in production NumPy code.
import numpy as np
batch_A = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
batch_B = np.array([[[1, 0], [0, 1]], [[2, 0], [0, 2]]])
result = np.matmul(batch_A, batch_B)
print(result.shape)3Best Practices
Follow these guidelines when working with np.matmul():
1. Use @ (or np.matmul()) as the default for matrix multiplication, reserving * strictly for element-wise multiplication
2. Check that inner dimensions actually match, columns of the left matrix equal rows of the right, before multiplying, to catch shape errors early
3. Rely on matmul()'s batched behavior for 3D+ arrays, like multiplying a batch of matrices at once, instead of writing an explicit loop over the batch dimension
Tip: Use @, which calls np.matmul() internally, as your default for matrix multiplication in NumPy code — it reads cleanly, matches standard linear algebra conventions, and handles batched 3D+ matrix multiplication predictably, unlike np.dot().
import numpy as np
A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])
print(A @ B)