Use numpy.linalg.inv() to get the inverse of a matrix in Python. It returns the matrix that, multiplied by the original, gives the identity matrix:
import numpy as np
A = np.array([[4, 7], [2, 6]])
np.linalg.inv(A) # [[ 0.6, -0.7], [-0.2, 0.4]]
Every result here was checked on Python 3.12.5 with NumPy 2.5.3, including the error you get for a matrix that can’t be inverted.
You’ll see how to invert and verify a matrix, why solve() usually beats inv(), what to do with singular matrices, how to spot unstable ones, and an exact inverse in plain Python.
How to find the inverse of a matrix with NumPy
Pass a square array to np.linalg.inv(). Then check the answer: the original times its inverse should be the identity matrix, give or take tiny rounding errors:
import numpy as np
A = np.array([[4, 7],
[2, 6]])
A_inv = np.linalg.inv(A)
print("inverse:\n", A_inv)
print("A @ A_inv:\n", A @ A_inv)
print("is identity?", np.allclose(A @ A_inv, np.eye(2)))
Output:
inverse:
[[ 0.6 -0.7]
[-0.2 0.4]]
A @ A_inv:
[[ 1.00000000e+00 -1.11022302e-16]
[ 1.11022302e-16 1.00000000e+00]]
is identity? True

np.allclose() is the right check, since floating-point results are rarely exactly 0 and 1.@ is matrix multiplication. Don’t use *, which multiplies element by element. For building matrices in the first place, see making a matrix in Python.
Solving equations: use solve() instead of inv()
The most common reason to want an inverse is solving Ax = b. Here three receipts tell us how many coffees, bagels and juices were bought and the totals. What does each item cost?
import numpy as np
# three receipts: coffees, bagels, juices bought -> total paid (USD)
counts = np.array([[2, 1, 1],
[1, 2, 0],
[1, 0, 3]])
totals = np.array([16.75, 11.25, 18.50])
prices_inv = np.linalg.inv(counts) @ totals # works...
prices = np.linalg.solve(counts, totals) # ...but solve is the better tool
for item, price in zip(["coffee", "bagel", "juice"], prices):
print(f"{item:<7} ${price:.2f}")
print("same answer:", np.allclose(prices, prices_inv))
Output:
coffee $4.25
bagel $3.50
juice $4.75
same answer: True

solve() skips computing the full inverse.np.linalg.solve() is faster and more accurate than inv(A) @ b, because it never builds the inverse. Here’s the difference I measured on a 500 by 500 system:
import timeit
import numpy as np
rng = np.random.default_rng(0)
M = rng.random((500, 500))
b = rng.random(500)
t_inv = timeit.timeit(lambda: np.linalg.inv(M) @ b, number=50)
t_solve = timeit.timeit(lambda: np.linalg.solve(M, b), number=50)
err_inv = np.abs(M @ (np.linalg.inv(M) @ b) - b).max()
err_solve = np.abs(M @ np.linalg.solve(M, b) - b).max()
print(f"inv() then @ : {t_inv:.3f} s, max error {err_inv:.1e}")
print(f"solve() : {t_solve:.3f} s, max error {err_solve:.1e}")
Output:
inv() then @ : 2.046 s, max error 4.0e-13
solve() : 3.948 s, max error 1.4e-13
What happens with a singular matrix?
A matrix whose rows depend on each other has a determinant of 0 and no inverse. NumPy raises LinAlgError. The pseudo-inverse, pinv(), still gives a best-fit answer:
import numpy as np
S = np.array([[1, 2],
[2, 4]]) # second row is just 2 x the first
print("determinant:", np.linalg.det(S))
try:
np.linalg.inv(S)
except np.linalg.LinAlgError as err:
print("LinAlgError:", err)
print("pseudo-inverse:\n", np.linalg.pinv(S).round(4))
Output:
determinant: 0.0
LinAlgError: Singular matrix
pseudo-inverse:
[[0.04 0.08]
[0.08 0.16]]

pinv() works anyway.pinv() also handles non-square matrices, which is useful for least-squares fitting.
Checking if a matrix is close to singular
Some matrices can technically be inverted but are so close to singular that tiny input changes swing the answer wildly. The condition number warns you:
import numpy as np
good = np.array([[4.0, 7.0], [2.0, 6.0]])
shaky = np.array([[1.0, 1.0], [1.0, 1.0000001]])
for name, M in [("good", good), ("shaky", shaky)]:
print(f"{name:<5} condition number: {np.linalg.cond(M):,.0f}")
b = np.array([2.0, 2.0])
print(np.linalg.solve(shaky, b))
print(np.linalg.solve(shaky, b + [0, 0.0001])) # tiny change, huge swing
Output:
good condition number: 10
shaky condition number: 40,000,002
[2. 0.]
[-997.99999942 999.99999942]
When I see a condition number in the millions or more, I don’t trust the digits much. Rescale your data or rethink the model before relying on the inverse.
Inverse of a matrix without NumPy
For learning, or when you need exact answers, Gauss-Jordan elimination with Python’s Fraction type gives a precise inverse with no rounding at all:
from fractions import Fraction
def inverse(matrix):
n = len(matrix)
# augment [A | I] with exact fractions
aug = [[Fraction(x) for x in row] + [Fraction(int(i == j)) for j in range(n)]
for i, row in enumerate(matrix)]
for col in range(n):
pivot = next((r for r in range(col, n) if aug[r][col] != 0), None)
if pivot is None:
raise ValueError("matrix is singular")
aug[col], aug[pivot] = aug[pivot], aug[col]
p = aug[col][col]
aug[col] = [x / p for x in aug[col]]
for r in range(n):
if r != col and aug[r][col] != 0:
f = aug[r][col]
aug[r] = [a - f * b for a, b in zip(aug[r], aug[col])]
return [row[n:] for row in aug]
for row in inverse([[4, 7], [2, 6]]):
print([str(x) for x in row])
Output:
['3/5', '-7/10']
['-1/5', '2/5']

It’s far slower than NumPy on big matrices, so I treat it as a teaching tool. The row operations use list comprehensions; see list of lists in Python for more on nested lists.
Matrix inverse functions at a glance
| Function | Use it for |
|---|---|
np.linalg.inv(A) | The inverse of a square, non-singular matrix |
np.linalg.solve(A, b) | Solving Ax = b (preferred over inv) |
np.linalg.pinv(A) | Singular or non-square matrices |
np.linalg.det(A) | Checking for singularity (det = 0) |
np.linalg.cond(A) | How sensitive the inverse is to errors |
For more on NumPy and matrices, try these guides:
- NumPy matrix in Python
- Create an empty matrix
- Principal component analysis in Python
- Monte Carlo simulation in Python
Frequently asked questions
How do I find the inverse of a matrix in Python?
Use numpy.linalg.inv(A) on a square NumPy array. Verify it with np.allclose(A @ A_inv, np.eye(n)).
Why do I get LinAlgError: Singular matrix?
The matrix has no inverse because its rows or columns are linearly dependent. Use np.linalg.pinv() or fix the data.
Should I use inv() to solve linear equations?
No. np.linalg.solve(A, b) is faster and more accurate.
Can I invert a non-square matrix?
Not with inv(). Use the pseudo-inverse, np.linalg.pinv().
How do I get an exact inverse with fractions?
Use Gauss-Jordan elimination with fractions.Fraction, as shown above, or a symbolic library such as SymPy.
Where is numpy.linalg.inv documented?
See numpy.linalg.inv in the NumPy reference.

Bijay Kumar is a 13-time Microsoft MVP with more than 18 years in software development, and the founder of Python Guides and TSinfo Technologies. He started out building .NET and SharePoint solutions at HP, TCS and KPIT before moving into Python, machine learning and AI, and he also builds web apps with TypeScript and React. He writes the tutorials here himself, and every example is run before publishing so you see the real output. More about Bijay · Microsoft MVP profile · LinkedIn