scipy.interpolate.
make_lsq_spline#
- scipy.interpolate.make_lsq_spline(x, y, t, k=3, w=None, axis=0, check_finite=True, *, method='qr')[源代码]#
计算基于 LSQ (最小二乘) 拟合的 B 样条的(系数)。
结果是线性组合
\[S(x) = \sum_j c_j B_j(x; t)\]B 样条基元素,\(B_j(x; t)\), 它最小化
\[\sum_{j} \left( w_j \times (S(x_j) - y_j) \right)^2\]- 参数:
- xarray_like,形状 (m,)
横坐标。
- yarray_like,形状 (m, …)
纵坐标。
- tarray_like,形状 (n + k + 1,)。
节点。节点和数据点必须满足 Schoenberg-Whitney 条件。
- kint,可选
B 样条的阶数。默认是三次,
k = 3
。- warray_like,形状 (m,),可选
样条拟合的权重。必须是正数。如果为
None
,则所有权重相等。默认为None
。- axisint,可选
插值轴。默认为零。
- check_finitebool,可选
是否检查输入数组是否只包含有限数字。禁用可能会提高性能,但如果输入确实包含无穷大或 NaN,可能会导致问题(崩溃,不终止)。默认为 True。
- methodstr,可选
用于解决线性 LSQ 问题的方法。允许的值为“norm-eq”(显式构造并求解正规方程组)和“qr”(使用设计矩阵的 QR 分解)。默认为 “qr”。
- 返回:
- b一个 B 样条对象,阶数为
k
,节点为t
。
- b一个 B 样条对象,阶数为
另请参阅
BSpline
表示 B 样条对象的基础类
make_interp_spline
一个类似的用于插值样条的工厂函数
LSQUnivariateSpline
一个基于 FITPACK 的样条拟合程序
splrep
一个基于 FITPACK 的拟合程序
注释
数据点的数量必须大于样条的阶数
k
。节点
t
必须满足 Schoenberg-Whitney 条件,即必须存在一个数据点子集x[j]
使得t[j] < x[j] < t[j+k+1]
,对于j=0, 1,...,n-k-2
。示例
生成一些噪声数据
>>> import numpy as np >>> import matplotlib.pyplot as plt >>> rng = np.random.default_rng() >>> x = np.linspace(-3, 3, 50) >>> y = np.exp(-x**2) + 0.1 * rng.standard_normal(50)
现在用预定义的内部节点拟合一个平滑的三次样条。 这里我们通过添加边界节点使节点向量 (k+1)-正则
>>> from scipy.interpolate import make_lsq_spline, BSpline >>> t = [-1, 0, 1] >>> k = 3 >>> t = np.r_[(x[0],)*(k+1), ... t, ... (x[-1],)*(k+1)] >>> spl = make_lsq_spline(x, y, t, k)
为了比较,我们还为同一组数据构造一个插值样条
>>> from scipy.interpolate import make_interp_spline >>> spl_i = make_interp_spline(x, y)
绘制两者
>>> xs = np.linspace(-3, 3, 100) >>> plt.plot(x, y, 'ro', ms=5) >>> plt.plot(xs, spl(xs), 'g-', lw=3, label='LSQ spline') >>> plt.plot(xs, spl_i(xs), 'b-', lw=3, alpha=0.7, label='interp spline') >>> plt.legend(loc='best') >>> plt.show()
NaN 处理:如果输入数组包含
nan
值,则结果没有意义,因为底层样条拟合程序无法处理nan
。 一种解决方法是对非数字数据点使用零权重>>> y[8] = np.nan >>> w = np.isnan(y) >>> y[w] = 0. >>> tck = make_lsq_spline(x, y, t, w=~w)
请注意,需要将
nan
替换为数值(只要对应的权重为零,精确值无关紧要。)