Python学习-Scipy库插值处理
目录
1、单变量插值, 一维插值interpld()
2、多变量插值 网格数据二维插值 griddata()
3、样条插值 InterpolatedUnivariateSpline类对象
插值就是根据已知数据点(条件),来预测未知数据点值得方法。
具体来说,假如你有n个已知条件,就可以求一个n-1次的插值函数P(x),使得P(x)接近未知原函数f(x),并由插值函数预测出你需要的未知点值。而又n个条件求n-1次P(x)的过程,实际上就是求n元一次线性方程组。
导入库
import scipy.interpolate as ipl
import numpy as np
import matplotlib.pyplot as plt
plt.rc('font', family='simhei', size=15) # 设置中文显示,字体大小
plt.rc('axes', unicode_minus=False) # 该参数解决负号显示的问题
1、单变量插值, 一维插值interpld()
参数说明:
x: 离散数据点的x坐标值,一维数组
y: 离散数据点的y坐标值,一维数组
kind: 插值类型,‘nearest’&'zero’0阶样条插值,‘linear’&'slinear’1阶样条插值,
'quadratic’2阶样条插值,'cubic’3阶样条插值,‘previous’&'next’只返回某一点的上一个、下一个值
axis: 多维y需要插值的维度,默认第一维度
copy: 对x,y数据的使用类型,复制or视图
bounds_error: True,插值超过x的范围时引发报错;False,超出范围时,分配填充值
fill_value: 填充值
assume_sorted: False,x可以是任何顺序;True,x必须是单调递增
**返回值:**一个函数对象f(x)
代码:
np.random.seed(29929)
x = np.random.randn(10)
y = np.random.randn(10)
f = ipl.interp1d(x=x, y=y, kind='cubic')
x_new = np.linspace(start=x.min(), stop=x.max(), num=80)
y_new = f(x_new)
plt.figure(1)
plt.plot(x, y, 'ro')
plt.plot(x_new, y_new, 'g-')
plt.title('一维插值曲线图')
plt.show()
输出:
2、多变量插值 网格数据二维插值 griddata()
参数说明:
points: 数据坐标点,形为(n,D)的数组,或为多维数组的元组
values: 浮点或复数的多维数组形为(n,)的数组
xi: 浮点型二维数组或一维数组的元组,形状为(M,D)的插值点
method: 插值方法,'linear’基于三角形的线性插补法,返回最近插值点的数据点的值;
'nearest’最近邻居插补法,将输入点设置为n维单形,并在每个单形上进行插补;
'cubic’一维,返回由三次样条确定的值;二维,返回由分段三次补差、连续可微分和近似率最小化多项式表面确定的值
fill_value: 用于填充输入点凸包外部的请求点值
rescale: 执行插值之前,重新缩放基于单位立方体的points值
代码:
def func(x, y):
return x*(1-x)*np.cos(4*np.pi*x) * np.sin(4*np.pi*y**2)**2
grid_x, grid_y = np.mgrid[0:1:100j, 0:1:200j] # 网格点坐标
points = np.random.rand(1000, 2) # 1000行,2列坐标
values = func(points[:, 0], points[:, 1]) # 获取实际的点
grid_z0 = ipl.griddata(points=points, values=values, xi=(grid_x, grid_y), method='nearest') # 用最近邻居插补法进行插值计算并计算网格点的值
grid_z1 = ipl.griddata(points=points, values=values, xi=(grid_x, grid_y), method='linear') # 用线性补差法进行插值计算并计算网格点的值
grid_z2 = ipl.griddata(points=points, values=values, xi=(grid_x, grid_y), method='cubic') # 用三次补差法进行插值计算并计算网格点的值
# 画图
plt.figure(2, figsize=(10, 10))
# 绘制实际的点
plt.subplot(221)
plt.imshow(X=func(grid_x, grid_y).T, extent=(0, 1, 0, 1), origin='lower')
plt.plot(points[:, 0], points[:, 1], 'k.', ms=1)
plt.title('原始网格数据')
# 绘制运用最邻近补差法进行插值的点
plt.subplot(222)
plt.imshow(X=grid_z0.T, extent=(0, 1, 0, 1), origin='lower')
plt.title('最近邻居插补法')
# 绘制运用线性补差法进行插值的点
plt.subplot(223)
plt.imshow(X=grid_z1.T, extent=(0, 1, 0, 1), origin='lower')
plt.title('线性补差法')
# 绘制运用线性补差法进行插值的点
plt.subplot(224)
plt.imshow(X=grid_z2.T, extent=(0, 1, 0, 1), origin='lower')
plt.title('三次补差法')
plt.show()
输出:
3、样条插值
样条插值以多项式作为任意相邻两个数据点平滑曲线计算方式,最终形成经过所有离散点的光滑曲线的数学方法。
一维平滑样条:InterpolatedUnivariateSpline类对象
参数说明;
x: 离散数据点的x坐标,必须是增量
y: 离散数据点的y坐标
w: 样条拟合的权重分配,必须是正数
bbox: 近似区间边界的序号值,[x[0], x[-1]]
k: 平滑样条拟合程度的值,必须是[1,5]范围的值
ext: 控制元素的外推模式,0或’extrapolate’返回外推值;1或’zeros’返回0;2或’raise’引发错误,3或’const’返回边界值
cheek_finite: 检查输入数据是否含有inf、nan、异常值
代码:
np.random.seed(29292)
x = np.linspace(-5, 5, 20) # 离散样点的x坐标
y = np.exp(-x**2) + 0.01*np.random.randn(20) + 1
spl = ipl.InterpolatedUnivariateSpline(x, y)
plt.figure(3)
plt.plot(x, y, 'r*', markeredgewidth=3)
xs = np.linspace(-5, 5, 100)
plt.plot(xs, spl(xs), 'b', lw=2)
plt.title('一维平滑样条插值曲线')
plt.show()
输出: