numpy polyfit RankWarning: Polyfit may be poorly conditioned (tested)
RankWarning: Polyfit may be poorly conditioned means the fit is rank-deficient: the degree is too high for the number of points, or large x values (like years) make the matrix numerically singular. Center/scale x (or use Polynomial.fit), lower the degree, and drop NaN values first, which otherwise give all-NaN coefficients silently.
1. The warning and the errors, reproduced
Run with python b1.py (numpy 2.5.4, Python 3.13.5):
import numpy as np
print("numpy", np.__version__)
x = np.arange(10, dtype=float)
y = x ** 2
# 1. degree higher than the data supports
c = np.polyfit(x[:3], y[:3], deg=5)
print("deg 5 on 3 points:", np.round(c, 3))
# 2. huge x values (years) with a high degree
years = np.arange(2000, 2021, dtype=float)
vals = np.sin(years)
c = np.polyfit(years, vals, deg=8)
# 3. NaN in the data
y_nan = y.copy(); y_nan[3] = np.nan
try:
print("NaN in y ->", np.polyfit(x, y_nan, 1))
except np.linalg.LinAlgError as e:
print("NaN -> LinAlgError:", e)
# 4. too few points / mismatched lengths
for args in [(x[:0], y[:0]), (x, y[:5])]:
try:
np.polyfit(*args, 1)
except (TypeError, ValueError) as e:
print(type(e).__name__ + ":", e)
Output:
numpy 2.5.4
/tmp/pf403/b1.py:8: RankWarning: Polyfit may be poorly conditioned
c = np.polyfit(x[:3], y[:3], deg=5)
deg 5 on 3 points: [ 0.016 0.036 0.089 0.236 0.623 -0. ]
/tmp/pf403/b1.py:14: RankWarning: Polyfit may be poorly conditioned
c = np.polyfit(years, vals, deg=8)
NaN in y -> [nan nan]
TypeError: expected non-empty vector for x
TypeError: expected x and y to have same length
RankWarning: Polyfit may be poorly conditionedis a warning, not an exception:polyfitstill returned coefficients. It means the least-squares matrix is rank-deficient, so some coefficients are not determined by your data.- Case 1: degree 5 through 3 points. Any degree ≥ the number of points is underdetermined; the six coefficients printed are one arbitrary solution out of infinitely many.
- Case 2: x values around 2000 raised to the 8th power (~2.6e26) next to the constant column (1) make the matrix numerically singular, even with 21 points.
- Case 3: a single
NaNinygave all-NaN coefficients with no warning and no error. - Case 4: empty input and length mismatch raise
TypeErrorwith the messages shown.
2. Fixes that worked
import warnings
import numpy as np
from numpy.polynomial import Polynomial
years = np.arange(2000, 2021, dtype=float)
vals = np.sin(years)
# full=True returns the rank instead of only warning
c, res, rank, sv, rcond = np.polyfit(years, vals, 8, full=True)
print("full=True: rank", rank, "of", 8 + 1)
# shift/scale x first
c = np.polyfit(years - 2000, vals, 8)
print("years - 2000: fitted, no warning")
# Polynomial.fit maps x to [-1, 1] internally
p = Polynomial.fit(years, vals, 8)
print("Polynomial.fit: no warning, domain", p.domain)
# catch it as an exception
try:
np.RankWarning
except AttributeError as e:
print("AttributeError:", str(e)[:80])
with warnings.catch_warnings():
warnings.simplefilter("error", np.exceptions.RankWarning)
try:
np.polyfit(years, vals, 8)
except np.exceptions.RankWarning as e:
print("raised:", e)
# NaN: drop missing points first
x = np.arange(10, dtype=float); y = x ** 2; y[3] = np.nan
ok = ~np.isnan(y)
print("after dropping NaN:", np.round(np.polyfit(x[ok], y[ok], 2), 6))
Output:
full=True: rank 6 of 9
years - 2000: fitted, no warning
Polynomial.fit: no warning, domain [2000. 2020.]
AttributeError: module 'numpy' has no attribute 'RankWarning'
raised: Polyfit may be poorly conditioned
after dropping NaN: [1. 0. 0.]
full=Truereturns the effective rank (6 of 9 here) instead of only warning, so you can check it in code.- Centering x (
years - 2000) removed the warning for the same degree.numpy.polynomial.Polynomial.fitdoes this for you: it maps the xdomain(here 2000 to 2020) to [-1, 1] before fitting. Callp(x)to evaluate it; its coefficients refer to the scaled variable, not raw x. - In numpy 2,
np.RankWarningno longer exists (AttributeError); the class isnp.exceptions.RankWarning. Use it withwarnings.simplefilter("error", ...)to make the fit fail loudly. - Drop NaN points with a mask (
~np.isnan(y)) before fitting. The fit then recovers y = x² exactly.
If the warning remains after scaling, lower the degree: a high-degree polynomial through noisy data rarely means anything outside the fitted points.
Related: numpy LinAlgError: Singular matrix · numpy errstate · numpy 2 breaking changes.
Frequently asked questions
What does RankWarning: Polyfit may be poorly conditioned mean?
The least-squares matrix is rank-deficient: the polynomial degree is too high for the data or x values are so large that powers of x swamp the other columns. Coefficients are returned but not reliable.
How do I fix a poorly conditioned polyfit?
Center or scale x (e.g. years - 2000), or use numpy.polynomial.Polynomial.fit which scales the domain to [-1, 1]; lower the degree if the warning remains.
Why does np.polyfit return nan?
A NaN in x or y makes all coefficients NaN without a warning. Remove missing points with a mask such as ~np.isnan(y) before fitting.
Where is np.RankWarning in numpy 2?
It was removed from the main namespace; use np.exceptions.RankWarning.
Written with AI assistance. Measured on 2026-10-23 with numpy 2.5.4 and Python 3.13.5 on Linux. Each script was run verbatim and the output pasted unedited. PlainTables is our extension; numpy is free.