插值:求一函数\(f(x)\)使其穿过给定的所有数据点\((x_i,y_i)\)
在数据分析中很有用
拉格朗日插值(Lagrange)
拉格朗日插值的\(f(x)\)为\(n-1\)次多项式,\(n\)为数据点个数
可以证明,任意\(n\)个数据点的\(n-1\)次插值函数存在且唯一
具体来说, \[ f(x)=\sum_{i=0}^n l_i(x)y_i \\ l_i(x)=\prod_{j=0,j\neq i}^n \frac {x-x_j} {x_i-x_j} \] 由此公式容易用Python实现拉格朗日插值
但是一次性将所有数据点进行插值,次数过高,不仅复杂度高,误差也大,因此常进行分段插值,即用分段函数表示\(f(x)\)
样条插值(spline)
单纯的分段插值得到的函数性质往往不够好(光滑性)
对于划分:\(\Delta:a=x_0<x_1<\dots<x_n=b\),\(m\)阶样条插值函数需要满足:
- 在每个小区间\([x_i,x_{i+1}](i=0,1,\dots,n-1)\)上是\(m\)次多项式
- 在区间\([a,b]\)上具有\(m-1\)阶导数
显然阶梯插值为0阶样条插值,折线插值为1阶样条插值
一般直接使用scipy.interpolate
实现的样条插值
scipy.interpolate
求解插值问题
一维插值(interp1d
)
interp1d(x,y,kind='linear')
前两个参数为数据点向量,kind指定插值方法:
kind | 说明 |
---|---|
'next','previous' |
阶梯插值,值为最近的前/后一个\(y_i\) |
'zero', 'linear', 'quadratic', 'cubic' |
0,1,2,3阶样条插值 |
0,1,2,3,5,... |
用int 指定样条插值的阶数,3以上只能为奇数 |
返回一个插值函数,可以传入\(x\)返回\(f(x)\),也可以传入\(\vec x\)返回\(f(\vec x)\)
示例:
1 | import numpy as np |
二维插值(interp2d
)
interp2d(x,y,z,kind='linear')
接受网格分布的数据点进行插值
x,y为坐标向量,z为数据矩阵
返回一个插值函数,输入x,y向量即可获得数据矩阵
1 | from IPython.core.pylabtools import figsize |
散点插值(griddata
)
若数据点并无分布规律,可用griddata
进行插值
可处理任意D维的数据点
griddata(points, values, xi, method='linear')
points
为数据点位置(D维向量)的序列,values
为数据点值的序列
xi
为需要插值的空间,形式与points
相同,或用格点坐标矩阵的D元组表示
method
插值方法:'nearest','linear','cubic'
分别对应0,1,3阶插值
返回xi
中的数据值
1 | from mpl_toolkits import mplot3d |