Python 中常用的插值方法
Python中的插值模块是scipy.interpolate,在惯性传感器的处理中主要用到一维的插值函数interp1d。Inter1d函数包含常用的**四种插值方法:分段线性插值,临近插值,球面插值,三次多项式插值。**而Spline就对应其中的三次多项式插值。插值的步骤应该是先根据已有序列拟合出一个函数,然后再在这个序列区间中均匀采样n次,得到插值后的n个序列。
我们选择较常用的线性插值和三次多项式插值为例,若我们将一个长度为10的序列插值到长度为30的序列,两种算法的效果如下。
1.给定原序列
(1)给定序列y=[3,5,9,7,18,16,6,5,9,10]
(2)设定横轴x=np.linespace(0,9,num=10)即横轴为[0,1,2,3,4,5,6,7,8,9]
(3)给定序列的图如下
2.分段线性插值
(1)f1=interp1d(x , y , kind=’linear’)
这里的f1相当于分段线性函数,是把原数据分为很多段,每一段都拟合为一维线性函数,最后再组合成整体的分段线性函数。
(2)x_pred=np.linspace(0,9,num=30)
设定插值的点,原序列的区间是[0,9],我们所谓的插值就是在这区间内均匀取30个点,然后作为我们插值的位置。
(3)插值后的图如下
蓝色的圆点为原序列的取值点,红色的’x’代表插值函数选取的插值点,将插值后的点连起来就为红色的线,可以看到是一段一段的直线。
3.三次多项式插值
(1)f2=interp1d(x , y , kind=’cubic’)
这里的f2相当于分段三次多项式函数,把原数据分为很多段,每一段都拟合为三次多项式函数,最后再组合成整体的函数。
(2)x_pred=np.linspace(0,9,num=30)
设定插值的点,原序列的区间是[0,9],我们所谓的插值就是在这区间内均匀取30个点,然后作为我们插值的位置。
(3)插值后的图如下
蓝色的圆点为原序列的取值点,红色的’x’代表插值函数选取的插值点,将插值后的点连起来就为红色的线,可以看到与上面线性插值的图片相比,明显能看到曲线的模样,表示是在拟合的曲线上进行重新采样,达到插值的效果。
4.Spline
(1)spline又称三次方样条数据插值,就和上述三次多项式插值原理一样
(2)若有序列[y1,y2,…yn]对应在区间[a,b]中,把[a,b]分成n个小区间,把每个小区间内的序列拟合成一个三次函数,如下
(i = 0,1,2,3…n)
(3)整个序列相当于拟合成了多段三次函数拼接的曲线,且这些三次曲线中,任意相邻的曲线在相邻点的一阶导数和二阶导数都是与相等的,所以拼接起来的整体曲线是平滑的。
(4)再在[a,b]均匀取n个值,利用拟合的总体函数可以求出这个n个值对应的序列,达到插值到长度n的目的。
代码附录
import numpy as np
from matplotlib import pyplot as plt
from scipy.interpolate import interp1d
y=[3,5,9,7,18,16,6,5,9,10]
x=np.linspace(0,9,num=10)
#x=[0,1,2,3,4,5,6,7,8,9]
#画出原始的序列
plt.figure()
plt.plot(x,y,'ro')
plt.legend()
plt.show()
#将原始序列分成多段,用一次函数拟合为函数f1和用三次函数拟合为函数f2
f1=interp1d(x,y,kind='linear')
f2=interp1d(x,y,kind='cubic')
#在原区间内均匀选取30个点,因为要插值到长度30.
x_pred=np.linspace(0,9,num=30)
#用函数f1求出插值的30个点对应的值
y1=f1(x_pred)
#在图中画出插值的30个点并连成曲线
plt.figure()
plt.plot(x,y,'bo')
plt.plot(x_pred,y1,'-rx',label='linear')
plt.legend()
plt.show()
#用函数f2求出插值的30个点对应的值
y2=f2(x_pred)
#在图中画出插值的30个点并连成曲线
plt.figure()
plt.plot(x,y,'bo')
plt.plot(x_pred,y4,'-rx',label='cubic')
plt.legend()
plt.show()