Python 使用'scipy.interpolate.griddata'进行非常缓慢的插值`

Python 使用'scipy.interpolate.griddata'进行非常缓慢的插值`,python,numpy,matplotlib,scipy,Python,Numpy,Matplotlib,Scipy,在尝试插值“几乎”时,我遇到了scipy.interpolate.griddata异常缓慢的性能定期将网格化数据转换为地图坐标,以便可以使用matplotlib.pyplot.imshow绘制地图和数据,因为matplotlib.pyplot.pcolormesh花费的时间太长,并且在alpha等方面表现不佳 最佳示例(可下载输入文件): 绘图: fig, (ax1,ax2) = plt.subplots(1,2) ax1.axis(map_extent) ax1.imshow(topo,ext

在尝试插值“几乎”时,我遇到了
scipy.interpolate.griddata
异常缓慢的性能定期将网格化数据转换为地图坐标,以便可以使用
matplotlib.pyplot.imshow
绘制地图和数据,因为
matplotlib.pyplot.pcolormesh
花费的时间太长,并且在
alpha
等方面表现不佳

最佳示例(可下载输入文件):

绘图:

fig, (ax1,ax2) = plt.subplots(1,2)
ax1.axis(map_extent)
ax1.imshow(topo,extent=extent,cmap='Greys')

ax2.axis(map_extent)
ax2.imshow(topo,extent=extent,cmap='Greys')

ax1.imshow(zi, vmax=0.1, extent=extent, alpha=0.5, origin='lower')
ax1.plot(lon[0],lat[0], '--k', lw=3, zorder=10)
ax1.plot(lon[-1],lat[-1], '--k', lw=3, zorder=10)
ax1.plot(lon.T[0],lat.T[0], '--k', lw=3, zorder=10)
ax1.plot(lon.T[-1],lat.T[-1], '--k', lw=3, zorder=10)


ax2.pcolormesh(lons,lats,data, alpha=0.5)
ax2.plot(lon[0],lat[0], '--k', lw=3, zorder=10)
ax2.plot(lon[-1],lat[-1], '--k', lw=3, zorder=10)
ax2.plot(lon.T[0],lat.T[0], '--k', lw=3, zorder=10)
ax2.plot(lon.T[-1],lat.T[-1], '--k', lw=3, zorder=10)
结果:

注意,这不能通过简单地使用仿射变换旋转数据来实现

griddata
调用我的真实数据时,每次调用都需要80秒以上的时间,
pcolormesh
甚至需要更长的时间(超过2分钟!)。我已经看过杰米和乔·金顿的答案,但我想不出一个办法让它对我有用


我所有的数据集都有完全相同的
lons
lats
,因此基本上我需要将它们映射到地图的坐标,并对数据本身应用相同的转换。问题是我如何做到这一点

在忍受了
scipy.interpolate.griddata
极其缓慢的性能之后,我决定放弃
griddata
,转而使用图像转换。具体来说

所以对于上面的例子,上面问题中的一个,你可以得到输入文件,这是一段需要1.1毫秒的代码,而在上面的例子中,692毫秒需要重新填充部分

import cv2
new_data = data.T[::-1]

# calculate the pixel coordinates of the
# computational domain corners in the data array
w,e,s,n = map_extent
dx = float(e-w)/new_data.shape[1]
dy = float(n-s)/new_data.shape[0]
x = (lon.ravel()-w)/dx
y = (n-lat.ravel())/dy

computational_domain_corners = np.float32(zip(x,y))

data_array_corners = np.float32([[0,new_data.shape[0]],
                                 [0,0],
                                 [new_data.shape[1],new_data.shape[0]],
                                 [new_data.shape[1],0]])

# Compute the transformation matrix which places
# the corners of the data array at the corners of
# the computational domain in data array pixel coordinates
tranformation_matrix = cv2.getPerspectiveTransform(data_array_corners,
                                                   computational_domain_corners)

# Make the transformation making the final array the same shape
# as the data array, cubic interpolate the data placing NaN's
# outside the new array geometry
mapped_data = cv2.warpPerspective(new_data,tranformation_matrix,
                                  (new_data.shape[1],new_data.shape[0]),
                                  flags=2,
                                  borderMode=0,
                                  borderValue=np.nan)
我看到这个解决方案的唯一缺点是数据中有轻微偏移,如所附图像中的非重叠轮廓所示。重新填充的数据轮廓(可能更精确)为黑色,透视数据轮廓为“jet”色刻度

目前,我对性能优势方面的差异感到满意,我希望这个解决方案也能帮助其他人

应该有人(不是我…)找到一种改进griddata性能的方法:) 享受吧


我使用了numpy
ndimage.map\u坐标
。它工作得很好

从上述链接复制:


scipy.ndimage.interpolation.map_坐标(输入、坐标、输出=无、顺序=3、模式=常数、cval=0.0、预过滤器=真)

通过插值将输入数组映射到新坐标

坐标数组用于为输出中的每个点查找输入中相应的坐标。这些坐标处的输入值由请求顺序的样条插值确定

通过删除第一个轴,从坐标阵列的形状导出输出的形状。沿第一个轴的数组值是输入数组中的坐标,在该坐标处可以找到输出值

    from scipy import ndimage
    a = np.arange(12.).reshape((4, 3))
    a
    array([[  0.,   1.,   2.],
            [  3.,   4.,   5.],
            [  6.,   7.,   8.],
            [  9.,  10.,  11.]])
    ndimage.map_coordinates(a, [[0.5, 2], [0.5, 1]], order=1)
    [ 2.  7.]

@用户3197748,你能试着把你的答案应用到上面给出的例子吗?您可以在这里下载文件:对不起,只有在阅读代码并尝试运行它时,我才发现使用scipy.ndimage.interpolation.map_坐标是不合适的。但是,当我运行您的代码的第一个版本(带有网格数据的版本)时,只做了很小的修改(extent=>map\u extent),我发现代码很快就可以运行了。也许是因为我用的是Anaconda numpy mkl。
    from scipy import ndimage
    a = np.arange(12.).reshape((4, 3))
    a
    array([[  0.,   1.,   2.],
            [  3.,   4.,   5.],
            [  6.,   7.,   8.],
            [  9.,  10.,  11.]])
    ndimage.map_coordinates(a, [[0.5, 2], [0.5, 1]], order=1)
    [ 2.  7.]