Python function vectorization
I have an old function named old_func
that takes two positional arguments x
and as input y
. The function's input was written as follows: a tuple was introduced as input:
def old_func(position):
x, y = position
return x**2 + y**2
Now I want a quick and easy way to call a function on a grid of values:
xx = numpy.linspace(0, 1, 100) yy = numpy.linspace(0, 1, 100) X, Y = numpy.meshgrid(xx, yy) array_positions = (X,Y) old_fun(array_positions)
The goal is that every operation in x
a function is performed on all x
and the same for y
. I tried to vectorize the function using numpy.vectorize
but it doesn't work. I prefer not to modify the function to accept NumPy arrays because it will take too long.
source to share
The code below does the trick and saves you the hassle of creating array_positions
.
First use ravel
to flatten X
and Y
shape numpy arrays (10000,)
.
X_flattened = X.ravel()
Y_flattened = Y.ravel()
Then use apply_along_axis
to implement a custom function iteratively along the length of these flattened arrays.
float_array = np.apply_along_axis(old_func, 0, (X_flattened, Y_flattened))
Finally, change the output array to your desired shape (100, 100)
.
np.reshape(float_array, (100, 100))
source to share
Your own code should (and does) work fine:
def old_fun(position): x, y = position z = x**2 + y**2 return z xx = numpy.linspace(0,1,100) yy = numpy.linspace(0,1,100) X,Y = numpy.meshgrid(xx, yy) array_positions = (X,Y) Z = old_fun(array_positions)
Z.shape
now (100, 100)
.
In general, numpy arrays will work with any standard operator like +
and **
. Note that although yours old_fun
takes a tuple as input, and that tuple must be two values, the type of the two values ββcan be anything as long as that type supports mathematical operators. Both standard Python scanners and numpy arrays support them, so the code works fine.
A note on @JuanManuel's answer: while it works great, it is notapply_along_axis
specifically designed to be vectorized in the sense that people usually want to use it, i.e. getting good performance of numpy. apply_along_axis
will result in a slow Python loop rather than a fast C loop like correctly vectorized code. Your own code is using correct vectorization, so use that.
source to share