python内置插值函数_Python:插值interpolate模块
插值是离散函数逼近的重要⽅法,利⽤它可通过函数在有限个点处的取值状况,估算出函数在其他点处的近似值。与拟合不同的是,要求曲线通过所有的已知数据。SciPy的interpolate模块提供了许多对数据进⾏插值运算的函数,范围涵盖简单的⼀维插值到复杂多维插值求解。当样本数据变化归因于⼀个独⽴的变量时,就使⽤⼀维插值;反之样本数据归因于多个独⽴变量时,使⽤多维插值。
计算插值有两种基本的⽅法,1、对⼀个完整的数据集去拟合⼀个函数;2、对数据集的不同部分拟合出不同的函数,⽽函数之间的曲线平滑对接。第⼆种⽅法⼜叫做仿样内插法,当数据拟合函数形式⾮常复杂时,这是⼀种⾮常强⼤的⼯具。我们⾸先介绍怎样对简单函数进⾏⼀维插值运算,然后进⼀步深⼊⽐较复杂的多维插值运算。
1. ⼀维插值interp1d()
⼀维数据的插值运算可以通过函数interp1d()完成。其调⽤形式如下,它实际上不是函数⽽是⼀个类:
类scipy.interpolate.interp1d(x,y,kind ='linear',axis = -1,copy = True,bounds_error = None,fill_value = nan,假定
_sorted = False)
内插⼀维函数。
x和y是⽤于近似某些函数f:的值的数组 。此类返回⼀个函数,该函数的调⽤⽅法使⽤插值法查新点的值。y = f(x)
请注意,
参量:
x :(N,)array_like
⼀维实数数组。
y :(...,N,...)array_like
ND实数值数组。沿插值轴的y长度必须等于x的长度。
kind: str or int, optional
将内插类型指定为字符串(“线性”,“最近”,“零”,“线性”,“⼆次”,“三次”,“上⼀个”,“下⼀个”,其中“零”,“线性”,“ “ quadratic”和“ cubic”是指零阶,⼀阶,⼆阶或三阶的样条插值;“ previous”和“ next
”仅返回该点的上⼀个或下⼀个
值)或作为指定样条顺序的整数内插器使⽤。默认值为“线性”。
axis : int, optional
指定要沿其进⾏插值的y轴。插值默认为y的最后⼀个轴。
copy : bool, optional
如果为True,则该类将制作x和y的内部副本。如果为False,则使⽤对x和y的引⽤。默认为复制。
bounds_error : bool, optional
如果为True,则任何时候尝试对x范围之外的值进⾏插值都会引发ValueError(需要进⾏插值)。如果为False,则分配超出范围的值
fill_value="extrapolate"。
fill_value : array-like or (array-like, array_like) or “extrapolate”, optional如果是ndarray(或float),则此值将⽤于填充数据范围之外的请求点。如果未提供,则默认值为NaN。类阵列必须正确⼴播到⾮插值
轴的尺⼨。
如果是⼆元组,则第⼀个元素⽤作的填充值,第⼆个元素 ⽤作的填充值。不是2元素元组的任何元素(例如list或ndarray,不考虑形状)都被视为⼀个类似数组的⾃变量,意味着将两个边界都⽤作 。x_new < x[0]x_new > x[-1]below, above = fill_value, fill_value
如果“外推”,则数据范围外的点将被外推。
assume_sorted : bool, optional
如果为False,则x的值可以按任何顺序排列,并且将⾸先对其进⾏排序。如果为True,则x必须是单调递增值的数组。
下⾯的程序演⽰了通过不同的 kind参数,对⼀个正弦函数进⾏插值运算。⽰例代码:
import numpy as np
from scipy import interpolate
import pylab as pl
x=np.linspace(0,10,11)
y=np.sin(x)
xnew=np.linspace(0,10,101)
pl.plot(x,y,'ro')
list1=['linear','nearest']
list2=[0,1,2,3]
for kind in list1:
print(kind)
f=interpolate.interp1d(x,y,kind=kind)
#f是⼀个函数,⽤这个函数就可以插值点的函数值了:
ynew=f(xnew)
pl.plot(xnew,ynew,label=kind)
pl.legend(loc='lower right')
pl.show()
interp1d⽐Matlab的interp有些优势,因为返回的是函数,不需要在事先设定需要求解的点,⽽是在需要使⽤时调⽤函数。
这个是linear和nearest的效果:
这个是zero, slinear, quadratic, cubic
也就是0, 1, 2, 3 次样条插值,所以这⾥的参数可以⽤str,也可以⽤数字
linspace函数pythonnterp1d不能外推运算(外插值)
UnivariateSpline可以外插值
调⽤⽅式如下:
UnivariateSpline(x,y,w=None,bbox=[None,None],k=3,s=None)x,y是X-Y坐标数组
w是每个数据点的权重值
k为样条曲线的阶数
s为平滑参数。s=0,样条曲线强制通过所有数据点
s>0,满⾜
from scipy import interpolate
import numpy as np
x1=np.linspace(0,10,20)
y1=np.sin(x1)
sx1=np.linspace(0,12,100)
func1=interpolate.UnivariateSpline(x1,y1,s=0)#强制通过所有点
sy1=func1(sx1)
import matplotlib.pyplot as plt
plt.plot(x1,y1,'o')
plt.plot(sx1,sy1)
plt.show()
也就插值到(0,12),范围再⼤就不⾏了,毕竟插值的专长不在于预测import numpy as np
from scipy import interpolate
x2=np.linspace(0,20,200)
y2=np.sin(x2)+al(loc=0,scale=1,size=len(x2))*0.2
sx2=np.linspace(0,22,2000)
func2=interpolate.UnivariateSpline(x2,y2,s=8)
sy2=func2(sx2)
import matplotlib.pyplot as plt
plt.plot(x2,y2,'.')
plt.plot(sx2,sy2)
plt.show()
interp2d(x,y,z,kind='linear')
这⾥有⼏个注意事项:interp2d()中,输⼊的x,y,z先⽤ravel()被转成了⼀维数组
func()的输⼊必须是⼀维的,输出是⼆维的(有点奇怪,感觉完成度不⾼)
插值的源数据必须是等距⽹格。不然的haul,运⾏不保存但结果不对。
step1:⽣成数据
import numpy as np
def func(x,y):
return (x+y)*np.exp(-5*(x**2+y**2))
x,id[-1:1:8j,-1:1:8j]
z=func(x,y)
step2:插值
from scipy import interpolate
func=interpolate.interp2d(x,y,z,kind='cubic')
xnew=np.linspace(-1,1,100)
ynew=np.linspace(-1,1,100)
znew=func(xnew,ynew)#xnew, ynew是⼀维的,输出znew是⼆维的
xnew,id[-1:1:100j,-1:1:100j]#统⼀变成⼆维,便于下⼀步画图step3:画图
import mpl_toolkits.mplot3d
import matplotlib.pyplot as plt
ax=plt.subplot(111,projection='3d')
ax.plot_surface(xnew,ynew,znew)
ax.scatter(x,y,z,c='r',marker='^')
plt.show()
Rbf的优点是,排列可以⽆序,可以不是等距的⽹格
step1:随机⽣成点,并计算函数值
import numpy as np
def func(x,y):
return (x+y)*np.exp(-5*(x**2+y**2))
x=np.random.uniform(low=-1,high=1,size=100)
y=np.random.uniform(low=-1,high=1,size=100)
z=func(x,y)
step2:插值
from scipy import interpolate
func=interpolate.Rbf(x,y,z,function='multiquadric')
xnew,id[-1:1:100j,-1:1:100j]
znew=func(xnew,ynew)#输⼊输出都是⼆维
step3:画图
import mpl_toolkits.mplot3d
import matplotlib.pyplot as plt
ax=plt.subplot(111,projection='3d')
ax.plot_surface(xnew,ynew,znew)
ax.scatter(x,y,z,c='r',marker='^')
plt.show()
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论