これは、再実装しないとベクトル化できませんinterp_2d
。ただし、何らかのタイプの補間であると仮定interp_2d
すると、操作はおそらく線形です。これは、 、、およびに依存する (おそらくスパースな) 行列がどこにあるかlambda z0: interp_2d(x0, y0, z0, x1, y1)
とおそらく同等です。現時点では、関数を呼び出すことで、呼び出しごとにこの行列を暗黙的に再計算していますが、毎回同じです。そのマトリックスが何であるかを一度把握し、それを新しいものに何度も再適用する方が効率的です。np.dot(M, z0)
M
x0
y0
x1
y1
interp_2d
z0
以下は、非常に単純な 1D 補間の例です。
x0 = [0., 1.]
x1 = 0.3
z0_2d = "some very long array with shape=(2, n)"
def interp_1d(x0, z0, x1):
"""x0 and z0 are length 2, 1D arrays, x1 is a float between x0[0] and x0[1]."""
delta_x = x0[1] - x0[0]
w0 = (x1 - x0[0]) / delta_x
w1 = (x0[1] - x1) / delta_x
return w0 * z0[0] + w1 * z0[1]
# The slow way.
for i in range(n):
z1_2d[i] = interp_1d(x0, z0_2d[:,i], x1)
# Notice that the intermediate products w1 and w2 are the same on each
# iteration but we recalculate them anyway.
# The fast way.
def interp_1d_weights(x0, x1):
delta_x = x0[1] - x0[0]
w0 = (x1 - x0[0]) / delta_x
w1 = (x0[1] - x1) / delta_x
return w0, w1
w0, w1 = interp_1d_weights(x0, x1)
z1_2d = w0 * z0_2d[0,:] + w1 * z0_2d[1:0]
が非常に大きい場合n
は、100 倍をはるかに超える速度向上が期待できます。