SOLFIND
Web Lens
Portal home

Matrix Multiplication in Python: The Complete Decision Guide

https://roadmap.sh/python-data-analysis/matrix-multiplication • 158 KB fetched
Open original page


Matrix Multiplication in Python: The Complete Decision Guide AI Tutor
*
Roadmaps
* AI Tutor
Lesson Packs Newsletters

Loading...

Matrix Multiplication in Python: The Complete Decision Guide

Kimberly Fessel Prefer us on Google
Multiplication seems simple enough, and you probably haven’t worried about it much since you mastered your times tables years ago. But ready or not, matrices are about to upend everything you know about straightforward doubling and tripling.
Table of contents
* What is Matrix Multiplication?

* Method 1: Nested Loops to Multiply Two Matrices

* Method 2: Nested List Comprehension

* Method 3: NumPy dot()

* Method 4: NumPy matmul() / @ Operator for the Matrix Product

* Comparison Table of Matrix Multiplication

* Common Errors and Fixes in Python Programs

* Broadcasting for Matrix Multiplication

* Wrapping Up

In this article, we’ll define matrix multiplication from a mathematical perspective, then walk you through several options for multiplying matrices in Python . We’ll compare your choices to help you pick the right one and leave you with a few final “gotchas” to avoid. Whether you’re tracking compounding interest, bacteria growth, or rabbit populations, this multiplication article has you covered.
What is Matrix Multiplication?
Matrix multiplication is a fundamental mathematical operation that combines two matrices to produce a new matrix. To perform it, you’ll take the first row of the first matrix and multiply its individual components by the corresponding elements of the first column of the second matrix, then sum all products. Calculate the next element by doing the same for the first row of the first matrix and the second column of the second, and so on.
For example, below you can find how matrix multiplication works for two 2x2 matrices:
[ 1 2 3 4 ] ⋅ [ − 1       0       2 − 2 ] = [ 1 ⋅ ( − 1 ) + 2 ⋅ 2 1 ⋅ 0 + 2 ⋅ ( − 2 ) 3 ⋅ ( − 1 ) + 4 ⋅ 2 3 ⋅ 0 + 4 ⋅ ( − 2 ) ] = [ 3 − 4 5 − 8 ] \begin{align*}
\begin{bmatrix}
1 & 2 \\
3 & 4
\end{bmatrix}
\cdot
\begin{bmatrix}
-1 & \;\;0 \\
\;\;2 & -2
\end{bmatrix}
&=
\begin{bmatrix}
1\cdot(-1) + 2 \cdot 2 & 1\cdot0 + 2 \cdot (-2) \\
3\cdot (-1) + 4 \cdot 2 & 3 \cdot 0 + 4\cdot (-2)
\end{bmatrix}\\
&=
\begin{bmatrix}
3 & -4 \\
5 & -8
\end{bmatrix}
\end{align*} [ 1 3 ​ 2 4 ​ ] ⋅ [ − 1 2 ​ 0 − 2 ​ ] ​ = [ 1 ⋅ ( − 1 ) + 2 ⋅ 2 3 ⋅ ( − 1 ) + 4 ⋅ 2 ​ 1 ⋅ 0 + 2 ⋅ ( − 2 ) 3 ⋅ 0 + 4 ⋅ ( − 2 ) ​ ] = [ 3 5 ​ − 4 − 8 ​ ] ​
The output is another 2x2 matrix. You can also operate on non-square matrices , but the innermost dimensions of the matrices must match for the operation to be valid. That is, the first matrix must have the same number of columns as the number of rows in the second matrix. For example, you can find the product of a 2x3 matrix and a 3x4 matrix; the result will take on the outer dimensions, 2x4.
AI Tutor
Give me the generic formula for matrix multiplication for an n x m matrix and an m x p.

Method 1: Nested Loops to Multiply Two Matrices
You can use several different Python approaches to implement matrix multiplication. First, you may use nested loops for a pure Python approach that doesn’t require any external libraries.
To do so, you’ll build your two matrices as nested lists and initialize your result matrix with all zeros. Then build three nested loops:

* Outer loop: rows of the first matrix

* Middle loop: columns of the second matrix

* Inner loop: multiplying corresponding row/column elements and adding the products

This code multiplies the matrices from our initial example using three nested for loops :
python

A = [ [1, 2], [3, 4] ] B = [ [-1, 0], [2, -2] ] result = [ [0, 0], [0, 0] ] for i in range(len(A)): # rows of A for j in range(len(B[0])): # columns of B for k in range(len(B)): # columns of A/rows of B result[i][j] += A[i][k]*B[k][j] print(result) # Expected result: # [[3, -4], [5, -8]]

While for loops offer a great way to learn about the inner workings of matrix multiplication, they produce relatively verbose code and aren’t the most efficient technique for multiplying large matrices.
Method 2: Nested List Comprehension
For an alternative pure Python approach that requires less code, you could try nested list comprehensions . This method computes the same output as the nested for loops, but is more Pythonic and does not require initialization of the result matrix.
This is what the 2x2 matrix example looks like with nested list comprehensions. Notice how we rely on zip() to pair the corresponding row and column elements, zip(*B) to access each column vector of the second matrix, and sum() to add the pairwise products:
python

A = [ [1, 2], [3, 4] ] B = [ [-1, 0], [2, -2] ] result = [ [sum(a * b for a, b in zip(row, col)) for col in zip(*B)] for row in A ] print(result) # Expected result: # [[3, -4], [5, -8]]

While less verbose, this technique proves a bit harder to read for beginners. It’s also still not particularly efficient for heavy-duty matrix calculations.
AI Tutor
Show me how zip() works including an example with nested lists.

Method 3: NumPy dot()
For high-performance matrix multiplication, you’ll likely want to utilize the NumPy library . NumPy is an external library for fast, efficient numerical calculations and scientific computing. You’ll need to install it separately and import it each time you use it.
You’ll now create your two matrices as NumPy arrays . You can multiply them using NumPy’s np.dot() function. This function automatically handles the necessary row-column products and summations:
python

import numpy as np A = np.array([ [1, 2], [3, 4] ]) B = np.array([ [-1, 0], [2, -2] ]) result = np.dot(A, B) print(result) # Expected result: # [[ 3 -4] # [ 5 -8]]

This technique provides a highly concise, readable way to multiply arrays. It also proves to be much better suited to multiply large matrices efficiently. You will still need matrices with compatible dimensions to apply this function. You’ll receive a ValueError if the innermost dimensions of your matrices don’t match.
Dot Product and Scalar Multiplication
np.dot() offers different functionality depending on its inputs. If you supply two vectors (1-D arrays) to np.dot() , you’ll receive the dot product of those vectors as the output. The dot product works just like computing a single entry of matrix multiplication. Think of the first input vector as a row vector, while the second input vector is a column vector. Your output will be a single scalar value obtained by summing all the corresponding element products.
[ 2 − 2 ] ⋅ [ 3 1 ] = 2 ⋅ 3 + ( − 2 ) ⋅ 1 = 4 \begin{bmatrix}
2 & -2
\end{bmatrix}
\cdot
\begin{bmatrix}
3 \\
1
\end{bmatrix}
=
2\cdot 3 + (-2) \cdot 1
=
4 [ 2 ​ − 2 ​ ] ⋅ [ 3 1 ​ ] = 2 ⋅ 3 + ( − 2 ) ⋅ 1 = 4
And this is what the code looks like using np.dot() function:
python

import numpy as np a = np.array([2, -2]) # vector: only one set of brackets b = np.array([3, 1]) result = a.dot(b) print(result) # Expected result: # 4

You can also achieve scalar multiplication of a matrix with the np.dot() function if you input a matrix and a scalar value. Say, you’d like to scale your matrix A by a factor of 2; that is, you want to multiply every element of A by 2. We demonstrate how that works with np.dot() in the next example:
python

import numpy as np A = np.array([ [1, 2], [3, 4] ]) result = np.dot(A, 2) # second input is the scalar number 2 print(result) # Expected result: # [[2 4] # [6 8]]

AI Tutor
Provide examples to demonstrate how NumPy’s np.dot() functionality depends on its inputs.

Method 4: NumPy matmul() / @ Operator for the Matrix Product
While np.dot() works perfectly well for two-dimensional arrays, developers typically prefer another NumPy function, np.matmul() , when specifically multiplying matrices.
Here’s np.matmul() in action:
python

import numpy as np A = np.array([ [1, 2], [3, 4] ]) B = np.array([ [-1, 0], [2, -2] ]) result = np.matmul(A, B) print(result) # Expected result: # [[ 3 -4] # [ 5 -8]]

np.matmul() gives the same result as np.dot() for standard matrix multiplication, but the two functions differ when working with certain other input dimensions. Unlike np.dot() , np.matmul() does not accept scalar inputs, and its behavior for higher-dimensional arrays, sometimes called tensors, follows broadcasting rules. Its intent is, therefore, more straightforward when you specifically want matrix multiplication.
Python introduced the @ operator in version 3.5 specifically for matrix multiplication. It performs the same operation as np.matmul() with cleaner syntax. You can rewrite the multiplication line in the code above as:
python

result = A @ B

This proves particularly helpful when chaining products. If you want to multiply the output by another matrix C, you need only type A @ B @ C .
Comparison Table of Matrix Multiplication
With so many ways to multiply two matrices, you may be confused about which method to choose. Below you’ll find a handy comparison table that lists each technique along with its typical use case, strengths, and weaknesses.
Method
Library
Best Use Case
Strengths
Weaknesses

Nested loops
None
Learning how matrix multiplication works; very small matrices
Pure Python; transparent logic; easy to trace
Verbose; slow for large matrices

Nested list comprehensions
None
Small matrices
Shorter than explicit loops; no result initialization
Harder to read; inefficient for large matrices

np.dot()
NumPy
General numerical work; matrix multiplication alongside dot products
Concise; fast; supports several input types
Behavior changes with dimensionality; less explicit intent

np.matmul()
NumPy
Matrix multiplication, especially with higher-dimensional arrays
Clear matrix multiplication; broadcasting support
Requires NumPy; no scalar inputs

@ operator
None, but inputs should be NumPy arrays or comparable
Readable, concise matrix multiplication
Clean syntax; easy to chain; explicit intent
Requires objects that implement @; may be less familiar to beginners

Common Errors and Fixes in Python Programs
Python makes matrix multiplication feel simple, especially with syntax like the @ operator. There are a few details to pay special attention to, however. Here’s a quick summary of the most common issues you’ll see in practice.
Dimension / Shape Mismatch
The most common error happens when the innermost dimensions of your matrices don’t match. The number of columns in the initial matrix must match the number of rows in the second for the operation to be valid. For two general matrices, the shapes should follow this pattern:
(m x n) @ (n x p) → (m x p)
For example, your matrices could be (3 x 2) @ (2 x 4) → (3 x 4) . These, however, are invalid: (2 x 3) @ (2 x 4) , since the innermost dimensions aren’t the same.
Unlike scalar multiplication, matrix multiplication is not commutative. In general A @ B ≠ B @ A . Furthermore, B @ A may not even be valid while A @ B is.
You may receive a ValueError error for mismatched shapes in NumPy. The exact message depends on your NumPy version and the function or operator you’re using, but could say “shapes not aligned.” Pure Python implementations may not provide a helpful dimension mismatch error. You might receive an IndexError or even calculate an incorrect output without an exception.
To avoid or correct this issue, double-check your matrix dimensions. Use the .shape attribute for NumPy arrays, or try len(A) for row counts and len(A[0]) to count columns if working with nested lists.
AI Tutor
Quiz me on matching dimensions to multiply two matrices.

dtype Issues
NumPy arrays generally use a single data type ( dtype ) for all their elements. NumPy matrix multiplication generally requires numeric values, and it may raise an error for non-numeric data.
NumPy attempts to do helpful dtype conversion when it encounters a mixed type array. Nonetheless, you may encounter errors if you have numeric values stored as strings.
Fix this problem by first checking the .dtype attribute to view the data type of your array. You may then make data type adjustments with the .astype() method (e.g. A.astype(float) ). Also keep in mind that integers and floats differ in how they represent values and handle numerical precision.
Confusing * and @
You may already be familiar with Python's multiplication operator , * , to take the product of scalar values (e.g. 2 * 3 → 6 ). It turns out that you can use * to do element-wise multiplication for NumPy arrays. This operator pairs each array value with the corresponding element in a second array and multiplies them. It does not do summation over rows or columns:
python

import numpy as np A = np.array([ [1, 2], [3, 4] ]) result = A * A print(result) # Expected result: # [[ 1 4] # [ 9 16]]

The @ operator, however, specifically multiplies matrices. You’ll likely receive an entirely different result when swapping these operators:
python

import numpy as np A = np.array([ [1, 2], [3, 4] ]) result = A @ A # swap in @ operator print(result) # Expected result: # [[ 7 10] # [15 22]]

Switching * and @ commonly leads to silent errors in Python programs when both operations are valid, so be sure to use @ for matrix multiplication and save * for elementwise or scalar multiplication.
Broadcasting for Matrix Multiplication
As a final consideration, NumPy can operate on arrays with different but compatible dimensions using a technique called broadcasting . This allows calculations between smaller and larger arrays without the need for copying or reshaping the data.
For example, when adding a row vector b to matrix A , NumPy assumes you want to add b to each row of matrix A :
python

import numpy as np A = np.array([ [1, 2], [3, 4] ]) b = np.array([10, 20]) result = A + b # add row vector b to each row of A print(result) # Expected result: # [[11 22] # [13 24]]

Broadcasting typically becomes relevant when taking the product of arrays with 3 or more dimensions (tensors). Both np.matmul() and the @ operator treat the final two axes as matrices, while considering earlier axes like batches of matrices. This becomes highly useful for performing the same matrix operation across many matrices, as in some machine learning algorithms.
AI Tutor
Use examples to describe broadcasting in Python including matrix multiplication.

Wrapping Up
Matrix multiplication is a common mathematical operation that combines two matrices into one output matrix. Python offers many different methods to achieve this including pure Python techniques like nested loops and list comprehensions, NumPy functions ( np.dot() and np.matmul() ), and the @ operator. To avoid the most common pitfalls, double-check your matrix dimensions and data types, and make sure you aren’t confusing the multiplication operator, * , with the matrix multiplication operator, @ .
Next, make sure you’ve got multiplication down pat by interacting with the AI Tutor. This prompt will get you started by clearing up any lingering confusion about * and @ :
AI Tutor
Explain the difference between the * and @ operators in Python.

Join the Community
roadmap.sh is the 6th most starred project on GitHub and is visited by hundreds of thousands of developers every month.
Rank  out of 28M!
367K
GitHub Stars

Star us on GitHub
Help us reach #1
+90k every month
+3.2M
Registered Users

Register yourself
Commit to your growth
+2k every month
51K
Discord Members

Join on Discord
Join the community

Roadmaps Guides FAQs YouTube
roadmap.sh by @nilbuild @nilbuild
Community created roadmaps, best practices, projects, articles, resources and journeys to help you choose your path and grow in your career.
© roadmap.sh · Terms · Privacy ·

The top DevOps resource for Kubernetes, cloud-native computing, and large-scale development and deployment.
DevOps · Kubernetes · Cloud-Native

Cookie Settings

Links found on this page

  1. AI Tutor [direct]
  2. Roadmaps [direct]
  3. Lesson Packs [direct]
  4. Newsletters [direct]
  5. Kimberly Fessel [direct]
  6. Prefer us on Google [direct]
  7. What is Matrix Multiplication? [direct]
  8. Python [direct]
  9. Python [direct]
  10. 6th most starred project on GitHub [direct]
  11. Star us on GitHub Help us reach #1 [direct]
  12. Register yourself Commit to your growth [direct]
  13. Join on Discord Join the community [direct]
  14. Guides [direct]
  15. FAQs [direct]
  16. YouTube [direct]
  17. roadmap.sh [direct]
  18. @nilbuild @nilbuild [direct]
  19. Terms [direct]
  20. Privacy [direct]
  21. DevOps [direct]
  22. Kubernetes [direct]
  23. Cloud-Native [direct]