scipy.interpolate.
make_lsq_spline#
- scipy.interpolate.make_lsq_spline(x, y, t, k=3, w=None, axis=0, check_finite=True)[source]#
计算基于最小二乘的拟合 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, shape (m,)
横坐标。
- yarray_like, shape (m, …)
纵坐标。
- tarray_like, shape (n + k + 1,).
结点。结点和数据点必须满足舍恩伯格-惠特尼条件。
- kint, optional
B 样条曲线幂。默认值为三次,
k = 3
。- w类似于数组的元素、形状 (m)、可选
用于样条曲线拟合的权重。必须为正数。如果
None
,则所有权重相等。默认值为None
。- axisint, 可选
对轴插值。默认值为零。
- check_finite布尔值, 可选
检查输入数组是否仅包含有限的数字。禁用可以提升性能,但如果输入包含无穷大或 NaN,则可能会产生问题(崩溃、终止)。默认值为 True。
- 返回:
- b幂为
k
、具有结点t
的 BSpline 对象。
- b幂为
另请参阅
BSpline
base 类,表示 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)-regular
>>> 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
替换为一个数值(只要相应权重为零,精确值并不重要)。