多项式#

NumPy 中的多项式可以使用 numpy.polynomial 包的 convenience classes 创建,操作甚至拟合,该包在 NumPy 1.4 中引入.

在 NumPy 1.4 之前, numpy.poly1d 是首选的类,为了保持向后兼容性,它仍然可用.但是,较新的 polynomial package 更完整,其 convenience classes 为处理多项式表达式提供了更一致,更好的接口.因此,建议新编码使用 numpy.polynomial .

备注

术语

术语多项式模块指的是在 numpy.lib.polynomial 中定义的旧 API,其中包括 numpy.poly1d 类和带有 poly 前缀的多项式函数,这些函数可以从 numpy 命名空间访问(例如 numpy.polyadd , numpy.polyval , numpy.polyfit 等).

术语多项式包指的是在 numpy.polynomial 中定义的新 API,其中包括针对不同类型多项式的便捷类( Polynomial , Chebyshev 等).

numpy.poly1d 过渡到 numpy.polynomial#

如上所述, poly1d class 和在 numpy.lib.polynomial 中定义的关联函数,如 numpy.polyfitnumpy.poly ,被认为是遗留的,不应在新代码中使用.自 NumPy 1.4 版本以来,建议使用 numpy.polynomial 包来处理多项式.

快速参考#

下表重点介绍了旧多项式模块和多项式包在常见任务中的一些主要区别.为简洁起见,导入 Polynomial 类:

from numpy.polynomial import Polynomial

如何…

旧版 ( numpy.poly1d )

numpy.polynomial

从系数创建多项式对象 [1]

p = np.poly1d([1, 2, 3])

p = Polynomial([3, 2, 1])

从根创建多项式对象

r = np.poly([-1, 1]) p = np.poly1d(r)

p = Polynomial.fromroots([-1, 1])

deg 次多项式拟合到数据

np.polyfit(x, y, deg)

Polynomial.fit(x, y, deg)

过渡指南#

numpy.lib.polynomialnumpy.polynomial 之间存在显著差异.最显著的区别是多项式表达式的系数顺序. numpy.polynomial 中的各种例程都处理系数从零次向上递增的级数,这与 poly1d 惯例的顺序相反.记住这一点最简单的方法是索引对应于次数,即 coef[i] 是 i 次项的系数.

虽然这种惯例上的差异可能会令人困惑,但从旧版多项式 API 转换为新的 API 很简单.例如,以下演示了如何将表示表达式 \(x^{2} + 2x + 3\)numpy.poly1d 实例转换为表示相同表达式的 Polynomial 实例:

>>> import numpy as np
>>> p1d = np.poly1d([1, 2, 3])
>>> p = np.polynomial.Polynomial(p1d.coef[::-1])

除了 coef 属性之外,多项式包中的多项式还具有 domainwindow 属性.这些属性在将多项式拟合到数据时最为相关,但应注意,具有不同 domainwindow 属性的多项式不被认为是相等的,并且不能在算术中混合使用:

>>> p1 = np.polynomial.Polynomial([1, 2, 3])
>>> p1
Polynomial([1., 2., 3.], domain=[-1.,  1.], window=[-1.,  1.], symbol='x')
>>> p2 = np.polynomial.Polynomial([1, 2, 3], domain=[-2, 2])
>>> p1 == p2
False
>>> p1 + p2
Traceback (most recent call last):
    ...
TypeError: Domains differ

有关 domainwindow 属性的更多详细信息,请参阅 convenience classes 的文档.

旧版多项式模块和多项式包之间的另一个主要区别是多项式拟合.在旧模块中,拟合是通过 polyfit 函数完成的.在多项式包中,首选 fit 类方法.例如,考虑将简单的线性拟合应用于以下数据:

In [1]: rng = np.random.default_rng()

In [2]: x = np.arange(10)

In [3]: y = np.arange(10) + rng.standard_normal(10)

使用旧版多项式模块,可以使用 polyfit 将线性拟合(即 1 次多项式)应用于这些数据:

In [4]: np.polyfit(x, y, deg=1)
Out[4]: array([ 1.07647214, -0.36802432])

使用新的 polynomial API,推荐使用 fit 类方法:

In [5]: p_fitted = np.polynomial.Polynomial.fit(x, y, deg=1)

In [6]: p_fitted
Out[6]: Polynomial([4.47610033, 4.84412465], domain=[0., 9.], window=[-1.,  1.], symbol='x')

注意,系数是在由 windowdomain 之间的线性映射定义的缩放域中给出的. convert 可用于获取未缩放数据域中的系数.

In [7]: p_fitted.convert()
Out[7]: Polynomial([-0.36802432,  1.07647214], domain=[-1.,  1.], window=[-1.,  1.], symbol='x')

polynomial 包的文档#

除了标准幂级数多项式外,polynomial 包还提供了几种其他类型的多项式,包括切比雪夫,埃尔米特(两种子类型),拉盖尔和勒让德多项式. 这些多项式中的每一个都有一个相关的 convenience class ,可以从 numpy.polynomial 命名空间中使用,它为处理多项式提供了一致的接口,而不管它们的类型如何.

有关为每种多项式单独定义的特定函数的文档,请参阅相应的模块文档:

旧式多项式的文档#