三线插值 - 没有Scipy的矢量化

时间:2014-12-19 23:41:53

标签: numpy 3d scipy interpolation

我希望对这段代码进行矢量化,但不知道从哪里开始。在这个网站上有另一个答案回答了我的类似问题:3D interpolation of NumPy arrays without SciPy,但我对如何实现它感到困惑。我不能使用SciPy中的任何东西,但是我需要我的代码很快,因为它对于大型数组的时间非常长(如你所料)。我意识到我的代码很慢,因为a)使用列表和b)使用嵌套for循环。

对于纬度(纬度)/经度(lon)/时间(t),我有一个常规的速度(V)网格。我希望能够为特定的纬度/经度/时间获得单个值。

我的代码如下:

def intrp_vel(lon_2_interp, lat_2_interp, t_2_interp, X, Y, T, V):
# lonlat should be a tuple of (lon, lat)
# t_2_interp should be a float of the current time step
# This function returns the surface velocity at any location in time.

Tlen = len(T)
Ylen = len(Y)-1
Xlen = len(X)-1

t_2_index = Tlen*(1-(T[-1]-t_2_interp)/(T[-1]-T[0]))
lat_2_index = Ylen*(1-(Y[-1]-lat_2_interp)/(Y[-1]-Y[0]))
lon_2_index = Xlen*(1-(X[-1]-lon_2_interp)/(X[-1]-X[0]))

time = np.linspace(0, Tlen, V.shape[0])
latitudes = np.linspace(0, Ylen, V.shape[1])
longitudes = np.linspace(0, Xlen, V.shape[2])

V1 = [] # To be brought down to 2D intp
V2 = [] # To be brought down to 1D intp
append1 = V1.append
for lats in latitudes:
    for lons in longitudes:
        append1(np.interp(t_2_index, time, V[:,lats,lons]))
V1 = np.reshape(V1, (len(Y),len(X)))
append2 = V2.append
for lons in longitudes:
    append2(np.interp(lat_2_index, latitudes, V1[:,lons]))

intrpvel = np.interp(lon_2_index, longitudes, V2)

return intrpvel

任何帮助都会非常感激,或者如果您理解上面链接中的代码,并且能够告诉我如何在我自己的情况下使用它。

1 个答案:

答案 0 :(得分:0)

以下是移除np.interp()的for循环调用的一些想法。

由于t_2_indextime不会在循环中发生变化,您可以使用np.interp()来计算V的线性混合参数。以下是确认这个想法的代码:

y = np.sin(x)
x2 = np.linspace(x[0]-1, x[-1]+1, 100)
y2 = np.interp(x2, x, y)

计算混合参数:

idx = np.arange(len(x))
idx_float = np.interp(x2, x, idx)
idx0 = idx_float.astype(int)
idx1 = np.clip(idx0 + 1, 0, len(x)-1)
a = idx_float - idx0
b = 1 - a

然后计算interp结果:

y3 = y[idx0] * b + y[idx1] * a
print np.allclose(y2, y3)

对于您的代码,如果您从idx0, idx1, a, bt_2_index计算time,则可以通过以下方式计算interp结果:

V[idx0, :, :] * b + V[idx1, :, :] * a