请考虑以下代码示例:
# %%
import numpy
from scipy.interpolate import interp2d, RegularGridInterpolator
x = numpy.arange(9000)
y = numpy.arange(9000)
z = numpy.random.randint(-1000, high=1000, size=(9000, 9000))
f = interp2d(x, y, z, kind='linear', copy=False)
f2 = RegularGridInterpolator((x, y), z, "linear")
mx, my = np.meshgrid(x, y)
M = np.stack([mx, my], axis=-1)
# %%
%timeit f(x, y)
# %%
%timeit f2(M)
字符串
它使用scipy.interpolate.interp2d
和scipy.interpolate.RegularGridInterpolator
建立了一些示例插值器。上面两个单元格的输出是
1.09 s ± 4.38 ms/循环(平均值±标准差)7次运行,每次1次循环)
和/或
10 s ± 17.6 ms/循环(平均值±标准值)7次运行,每次1次循环)
分别。RegularGridInterpolator
比interp2d
慢大约10倍。问题是interp2d
在scipy 1.10.0中被标记为已弃用。新代码应该使用RegularGridInterpolator
。这对我来说似乎有点奇怪,因为这将是一个如此糟糕的替代品。上面的代码示例中是否存在问题?如何加快插值过程?
2条答案
按热度按时间rwqw0loc1#
您的代码没有问题,可能是scipy中的bug。我已经在github上报告过了
p1iqtdky2#
如果其他人在这个问题上犯了错:
事实证明,手动计算双线性插值比scipy的
RegularGridInterpolator
快 * 10倍。当我说“手动”时,我的意思是:1.从传递给
RegularGridInterpolator
的相同points
(假设x_vals
长度为N,y_vals
长度为M)和values
(假设z_grid
形状为NxM)数组开始。1.给定你想要的坐标(比如
x,y
),使用np.searchsorted()
找到最近的四个点的索引(如果x_vals
/y_vals
是 * 递增 * --如果其中一个是 * 递减 *,这会自动工作,见下面的代码)。1.使用标准公式计算双线性插值,我使用Raymond Hettinger's code。
下面是我自己的实现中的一个稍微修改的摘录:
字符串
就像我之前说的,从我自己的测试来看,这比
RegularGridInterpolator
快了大约10倍。我不知道为什么scipy没有在文档中提供一个警告,我已经浪费了几个小时在这个lol上。但至少有一个干净的解决方案:>保重!