This cannot be vectorized without overriding interp_2d . However, assuming interp_2d is some type of interpolation, the operation is probably linear. This is lambda z0: interp_2d(x0, y0, z0, x1, y1) , probably equivalent to np.dot(M, z0) , where M is some (probably sparse) matrix that depends on x0 , y0 , x1 and y1 . Right now, by calling the interp_2d function, you implicitly recalculate this matrix with every call, although the same thing every time. It is more efficient to find out what this matrix is once and reapply it to the new z0 many times.
Here is a really trivial example of 1D interpolation:
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]
If n very large, expect speed to be well above 100.
source share