多项式#

NumPy 中的多项式可以创建操作,甚至使用 NumPy 1.4 中引入的便捷类进行拟合 numpy.polynomial 包。

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

注意

术语

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

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

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属性外,polynomial 包中的多项式还具有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属性的更多详细信息,请参阅便捷类的文档。

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

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

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

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

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

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

使用新的 polynomial API,首选fit类方法。

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

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

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

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

polynomial包文档#

除了标准幂级数多项式外,polynomial 包还提供了几种其他类型的多项式,包括 Chebyshev、Hermite(两种子类型)、Laguerre 和 Legendre 多项式。每种类型都具有一个相关的便捷类,可从numpy.polynomial命名空间获得,该命名空间提供了一个一致的接口,用于处理各种类型的多项式。

有关为每种类型的多项式单独定义的特定函数的文档,可以在相应的模块文档中找到。

旧版多项式文档#