Polynomials in NumPy can be created, manipulated, and even fitted using
the convenience classes
of the numpy.polynomial package, introduced in NumPy 1.4.
Prior to NumPy 1.4, numpy.poly1d was the class of choice and it is still
available in order to maintain backward compatibility.
However, the newer polynomial package is more complete
and its convenience classes provide a
more consistent, better-behaved interface for working with polynomial
Therefore numpy.polynomial is recommended for new coding.
The term polynomial module refers to the old API defined in
numpy.lib.polynomial, which includes the numpy.poly1d class and
the polynomial functions prefixed with poly accessible from the numpy
namespace (e.g. numpy.polyadd, numpy.polyval, numpy.polyfit, etc.).
The term polynomial package refers to the new API definied in
numpy.polynomial, which includes the convenience classes for the
different kinds of polynomials (numpy.polynomial.Polynomial,
As noted above, the poly1d class and associated
functions defined in numpy.lib.polynomial, such as numpy.polyfit
and numpy.poly, are considered legacy and should not be used in new
Since NumPy version 1.4, the numpy.polynomial package is preferred for
working with polynomials.
The following table highlights some of the main differences between the
legacy polynomial module and the polynomial package for common tasks.
The Polynomial class is imported for brevity:
from numpy.polynomial import Polynomial
from coefficients 1
p = np.poly1d([1, 2, 3])
p = Polynomial([3, 2, 1])
Create a polynomial
object from roots
r = np.poly([-1, 1])
p = np.poly1d(r)
r = np.poly([-1, 1])
p = np.poly1d(r)
p = Polynomial.fromroots([-1, 1])
Fit a polynomial of
degree deg to data
np.polyfit(x, y, deg)
Polynomial.fit(x, y, deg)
Note the reversed ordering of the coefficients
There are significant differences between numpy.lib.polynomial and
The most significant difference is the ordering of the coefficients for the
The various routines in numpy.polynomial all
deal with series whose coefficients go from degree zero upward,
which is the reverse order of the poly1d convention.
The easy way to remember this is that indices
correspond to degree, i.e., coef[i] is the coefficient of the term of
Though the difference in convention may be confusing, it is straightforward to
convert from the legacy polynomial API to the new.
For example, the following demonstrates how you would convert a numpy.poly1d
instance representing the expression to a
Polynomial instance representing the same
>>> p1d = np.poly1d([1, 2, 3])
>>> p = np.polynomial.Polynomial(p1d.coef[::-1])
In addition to the coef attribute, polynomials from the polynomial
package also have domain and window attributes.
These attributes are most relevant when fitting
polynomials to data, though it should be noted that polynomials with
different domain and window attributes are not considered equal, and
can’t be mixed in arithmetic:
>>> p1 = np.polynomial.Polynomial([1, 2, 3])
Polynomial([1., 2., 3.], domain=[-1, 1], window=[-1, 1])
>>> p2 = np.polynomial.Polynomial([1, 2, 3], domain=[-2, 2])
>>> p1 == p2
>>> p1 + p2
Traceback (most recent call last):
TypeError: Domains differ
See the documentation for the
convenience classes for further details on
the domain and window attributes.
Another major difference bewteen the legacy polynomial module and the
polynomial package is polynomial fitting. In the old module, fitting was
done via the polyfit function. In the polynomial package, the
fit class method is preferred. For
example, consider a simple linear fit to the following data:
In : rg = np.random.default_rng()
In : x = np.arange(10)
In : y = np.arange(10) + rg.standard_normal(10)
With the legacy polynomial module, a linear fit (i.e. polynomial of degree 1)
could be applied to these data with polyfit:
In : np.polyfit(x, y, deg=1)
Out: array([0.81228259, 1.41081669])
With the new polynomial API, the fit
class method is preferred:
In : p_fitted = np.polynomial.Polynomial.fit(x, y, deg=1)
In : p_fitted
Out: Polynomial([5.06608836, 3.65527167], domain=[0., 9.], window=[-1., 1.])
Note that the coefficients are given in the scaled domain defined by the
linear mapping between the window and domain.
convert can be used to get the
coefficients in the unscaled data domain.
In : p_fitted.convert()
Out: Polynomial([1.41081669, 0.81228259], domain=[-1., 1.], window=[-1., 1.])
In addition to standard power series polynomials, the polynomial package
provides several additional kinds of polynomials including Chebyshev,
Hermite (two subtypes), Laguerre, and Legendre polynomials.
Each of these has an associated
convenience class available from the
numpy.polynomial namespace that provides a consistent interface for working
with polynomials regardless of their type.
Documentation pertaining to specific functions defined for each kind of
polynomial individually can be found in the corresponding module documentation: