python interpolate_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,也可以用数字

nterp1d不能外推运算(外插值)

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)+np.random.normal(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,y=np.mgrid[-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,ynew=np.mgrid[-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,ynew=np.mgrid[-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()

你可能感兴趣的:(python,interpolate)