关于Pythonscipy.interpolate.interp2d插值函数的⼀个坑
1. interp2d函数⽤法
详见
linspace函数python2. 问题描述
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.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.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.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.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.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.show()
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的坑有不少,慎⽤!
程序⼩⽩,与君共勉!