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.

+3


source to share


2 answers


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))

      

+1


source


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.

+5


source







All Articles