关于Python scipy.interpolate.interp2d插值函数的一个坑

2023-05-16

scipy.interpolate.interp2d插值函数

博客地址:https://editor.csdn.net/md?not_checkout=1&articleId=109588264

1. interp2d函数用法

详见官方API文档

2. 问题描述

Python 3.8.3
Platform: Spyder 3
SciPy 1.5.0

在使用interp2d进行插值时,当输入的纵坐标顺序为正序时(递增序列,如[0, 1, 2, …10]),插值结果是正常的;而当输入逆序的纵坐标时(递减序列,如[10, 9, 8…,0]),插值结果会出现异常,如果不注意的话,程序会给出意想不到的插值结果,最后的插值结果会出现上下颠倒的情况。

# import module
from scipy import interpolate
import numpy as np
import matplotlib.pyplot as plt

先看一段插值结果为【正常】的代码:

# 插值结果正常
x = np.asarray([0,1,2])
y = np.asarray([0, 3])  #! 注意: 这里是正序
z = np.asarray([[1,2,3], [4,5,6]])
xx, yy = np.meshgrid(x, y)
plt.contourf(xx, yy, z)
plt.show()
# interp
xn = np.linspace(0, 2, num=8)
yn = np.linspace(0, 3, num=6)  #! 注意: 这里是正序
interpfunc = interpolate.interp2d(x, y, z, kind='linear')
zn = interpfunc(xn, yn)
xxn, yyn = np.meshgrid(xn, yn)
plt.contourf(xxn, yyn, zn)  # 展示插值结果
plt.show()

运行结果如图所示:
正序插值结果
再来看一下插值【不正常】的代码:

# 插值结果不正常
x = np.asarray([0,1,2])
y = np.asarray([3, 0])  #! 注意: 这里是逆序
z = np.asarray([[1,2,3], [4,5,6]])
xx, yy = np.meshgrid(x, y)
plt.contourf(xx, yy, z)
plt.show()
# interp
xn = np.linspace(0, 2, num=8)
yn = np.linspace(3, 0, num=6)  #! 注意: 这里是逆序
interpfunc = interpolate.interp2d(x, y, z, kind='linear')
zn = interpfunc(xn, yn)
xxn, yyn = np.meshgrid(xn, yn)
plt.contourf(xxn, yyn, zn)  # 展示插值结果
plt.show()

逆序插值结果

3. 解决办法

在程序中加入一个判断,如果输入的纵坐标为逆序,则使用numpy.flipud(array)的方法先将其进行上下倒置,则输出结果为正常。
代码如下【使用numpy.flipud()】:

# 解决interp2d插值结果倒置问题
x = np.asarray([0,1,2])
y = np.asarray([3, 0])  #! 注意: 这里是逆序
z = np.asarray([[1,2,3], [4,5,6]])
xx, yy = np.meshgrid(x, y)
plt.contourf(xx, yy, z)
plt.show()
# interp
xn = np.linspace(0, 2, num=8)
yn = np.linspace(3, 0, num=6)  #! 注意: 这里是逆序
# 这里假如判断函数, 如果输入的纵坐标为倒序, 则翻转插值矩阵
if y[0] > y[-1]:
	z = np.flipud(z)
interpfunc = interpolate.interp2d(x, y, z, kind='linear')
zn = interpfunc(xn, yn)
xxn, yyn = np.meshgrid(xn, yn)
plt.contourf(xxn, yyn, zn)  # 展示插值结果
plt.show()

使用flipud之后正常的插值结果

2020年12月13日补充:interp2d居然还有另外一个更隐蔽的坑。该函数插值生成的格点值与真实的(经纬度)坐标格点有错位,目前不知道怎么解决。。。现在使用iris模块的插值方法进行替换:

cube_intp = cube.interpolate(sample_points, iris.analysis.Linear())

iris的这个方法插值速度非常慢,比scipy的插值方法要慢很多很多。插值的详细代码不贴了,哎,处理了那么久的数据,结果发现错了,WDNMD。

4. 总结

一般情况下,插值所使用的坐标轴序列都是正序的,但是,有时候也会使用逆序列,如做某些地理处理,这时候常会遇到纬度序列为逆序,即从北纬90°N向南纬-90°S递减的序列,如果这时候直接使用该函数进行插值,结果就会出现问题。

scipy.interpolate.interp2d的坑有不少,慎用!

程序小白,与君共勉!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

关于Python scipy.interpolate.interp2d插值函数的一个坑 的相关文章

随机推荐