官方文档:/tutorial/interpolate
插值,即依据一系列点 ( x , y ) (x,y) (x,y) 通过一定的算法找到一个合适的函数来逼近这些点,反映出这些点的走势规律。当拟合出插值函数后便可用这个插值函数计算其他 x x x 对应的的 y y y 值,这就是插值的意义所在。
官方文档 :scipy.interpolate.interp1d
语法:
scipy.interpolate.interp1d(x, y, kind='linear', axis=-1, copy=True, bounds_error=None, fill_value=nan, assume_sorted=False)
其中,x
是一维数据;y
是 N 维数据且 y 在插值的方向轴上长度必须和 x 相等;kind
指定了插值类型(linear,nearest,zero,slinear,quadratic,cubic,previous,next),其中 zero,slinear,quadratic 和 cubic 指定了零、一、二、三阶样条插值;previous 和 next 仅仅返回当前点的前一个/后一个值。默认为 linear 线性插值。
from scipy.interpolate import interp1d
x = np.linspace(0, 10, num=11, endpoint=True)
y = np.cos(-x**2/9.0)
f = interp1d(x, y)
f2 = interp1d(x, y, kind='cubic')
xnew = np.linspace(0, 10, num=41, endpoint=True)
import matplotlib.pyplot as plt
plt.plot(x, y, 'o', xnew, f(xnew), '-', xnew, f2(xnew), '--')
plt.legend(['data', 'linear', 'cubic'], loc='best')
plt.show()
kind='linear(默认)'
:使用一次函数插值 f ( x ) = a x + b f(x) = ax+b f(x)=ax+b
kind='cubic'
:使用三次函数插值 f ( x ) = a x 3 + b x 2 + c x + d f(x) = ax^3+bx^2+cx+d f(x)=ax3+bx2+cx+d
官方文档 :scipy.interpolate.interp2d
样条插值需要两个基本步骤:
为了找到样条曲线表示,有两种不同的方法来表示曲线并获得(平滑)样条系数:直接法 和 参数法。
直接法: 用函数 splrep
求二维平面上曲线的样条表示。前两个是必要参数,提供了曲线上点的 x、y 坐标,函数返回值为三元组 ( t , c , k ) (t,c,k) (t,c,k), t t t 为结点, c c c 为系数, k k k 为样条顺序(默认为三次),可以通过输入参数 k
进行更改。
对于 N 维空间的曲线,函数 splprep
可以参数化地定义曲线。该函数第一个为必要参数,该输入为 N 维数组列表,表示了在 N 维空间中的曲线。数组长度是曲线上点的数目。函数返回值为 三元组 ( t , c , k ) (t,c,k) (t,c,k) 和变量 u u u
举例:
import numpy as np
import matplotlib.pyplot as plt
from scipy import interpolate
# Cubic-spline
x = np.arange(0, 2*np.pi+np.pi/4, 2*np.pi/8)
y = np.sin(x)
tck = interpolate.splrep(x, y, s=0)
xnew = np.arange(0, 2*np.pi, np.pi/50)
ynew = interpolate.splev(xnew, tck, der=0)
plt.figure()
plt.plot(x, y, 'x', xnew, ynew, xnew, np.sin(xnew), x, y, 'b')
plt.legend(['Linear', 'Cubic Spline', 'True'])
plt.axis([-0.05, 6.33, -1.05, 1.05])
plt.title('Cubic-spline interpolation')
plt.show()
x 和 y 是给定的一些坐标点,通过 splrep
函数计算出 B-spline 曲线的参数,再将该参数传递给 splev
函数计算出各个取样点 xnew
的插值结果。
官方文档 :scipy.interpolate.splrep
作用: 求取一维曲线的 B-spline 插值
给定一组数据点 ( x [ i ] , y [ i ] ) (x[i],y[i]) (x[i],y[i]),确定在区间 x b ≤ x ≤ x e xb ≤ x ≤ xe xb≤x≤xe 上 k k k 次的光滑样条逼近。
语法:
scipy.interpolate.splrep(x, y, w=None, xb=None, xe=None, k=3, task=0, s=None, t=None, full_output=0, per=0, quiet=1)
其中,x
和 y
是点的横纵坐标,xb
和 xe
是间隔,k
为样条拟合度,建议使用三次样条(cubic splines),通常 1 ≤ k ≤ 5 1 ≤ k ≤ 5 1≤k≤5
# splrep 应用
import matplotlib.pyplot as plt
from scipy.interpolate import splev, splrep
x = np.linspace(0, 10, 10)
y = np.sin(x)
spl = splrep(x, y)
x2 = np.linspace(0, 10, 200)
y2 = splev(x2, spl)
plt.plot(x, y, 'o', x2, y2)
plt.show()
官方文档 :scipy.interpolate.splprep
语法:
scipy.interpolate.splprep(x, w=None, u=None, ub=None, ue=None, k=3, task=0, s=None, t=None, full_output=0, nest=None, per=0, quiet=1)
作用: 求取 N 维曲线的 B-spline 插值
# 举例
phi = np.linspace(0, 2.*np.pi, 40)
r = 0.5 + np.cos(phi) # polar coords
x, y = r * np.cos(phi), r * np.sin(phi) # convert to cartesian
from scipy.interpolate import splprep, splev
tck, u = splprep([x, y], s=0)
new_points = splev(u, tck)
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.plot(x, y, 'ro')
ax.plot(new_points[0], new_points[1], 'r-')
plt.show()
x
:列表类型 [x,y]
,x 和 y 分别是表示曲线上坐标点的横纵坐标
w
:数组类型,长度与 x[0] 相同,默认为 ones(len(x[0]))
k
:spline 等级,推荐使用 Cubic splines(k=3),默认为 3
s
:float 类型,平滑条件,较大的 s 意味着曲线比较光滑,建议 s 的取值在 ( m − s q r t ( 2 ∗ m ) , m + s q r t ( 2 ∗ m ) ) (m-sqrt(2*m), m+sqrt(2*m)) (m−sqrt(2∗m),m+sqrt(2∗m)) 范围内
下图中, ( x , y ) (x,y) (x,y) 是实际定义的坐标点,表示为红色圆点;通过 splprep
函数拟合 x,y,得到拟合参数 tck 和 u,得到新的拟合曲线 new_points