This can not be vectorized without reimplementing interp_2d
. However, assuming interp_2d
is some type of interpolation, then the operation is probably linear. That is lambda z0: interp_2d(x0, y0, z0, x1, y1)
is 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 are implicitly recalculating this matrix on every call even though it is the same each time. It's more efficient to figure out what that matrix is once and reapply it to the new z0
many times.
Here is a really trivial 1D interpolation example:
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]
If n
is very large, expect a speed up of well over a factor of 100.
interp_2d
do? Without that information, there's no way to tell if it's possible to vectorize it. For applying a completely generic python function, the way you're doing it isn't going to be vastly slower than any of the other options. "Vectorizing" usually means re-writing the operation using numpy functions/expressions, rather than just applying wrappers likenumpy.vectorize
. (Which is understandably rather confusing...)interp_2d
is just bilinear, cubic, or nearest interpolation,scipy.ndimage.map_coordinates
orscipy.ndimage.zoom
can be used, depending on the relationship ofx0, y0
tox1, y
(are both on regular grids, or justz0
?).numpy.vectorize
to "vectorize" it, but there won't be any appreciable speedup. To usenumpy.vectorize
, just reorder the arguments in yourinterp_2d
function such thatz0
is the first argument (or use a wrapper function). This won't result in any noticeable speedup, though.