多项式#

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

在 NumPy 1.4 之前,numpy.poly1d 是首选类,并且为了保持向后兼容性,它仍然可用。然而,较新的 polynomial package 更为完善,其便捷类为处理多项式表达式提供了更一致、行为更好的接口。因此,新代码推荐使用 numpy.polynomial

注意

术语

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

术语*多项式包*指的是在 numpy.polynomial 中定义的新 API,它包括用于不同类型多项式的便捷类(PolynomialChebyshev 等)。

numpy.poly1d 过渡到 numpy.polynomial#

如上所述,在 numpy.lib.polynomial 中定义的 poly1d class 及相关函数,例如 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 属性的更多详细信息,请参阅 便捷类 的文档。

旧版多项式模块和多项式包之间的另一个主要区别是多项式拟合。在旧模块中,拟合是通过 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.18670859, -1.41420215])

使用新的多项式 API,更推荐使用 fit 类方法

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

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

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

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

polynomial 包的文档#

除了标准的幂级数多项式,多项式包还提供了几种额外的多项式类型,包括切比雪夫多项式、埃尔米特多项式(两种子类型)、拉盖尔多项式和勒让德多项式。每种多项式都有一个相关的便捷类,可从 numpy.polynomial 命名空间获取,为处理不同类型的多项式提供了统一的接口。

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

旧版多项式的文档#