Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Apply function on each row (row-wise) of a NumPy array

So, I have the function -

def function(x):     x , y = vector     return exp(((-x**2/200))-0.5*(y+0.05*(x**2) - 100*0.05)**2) 

and let's say that I would like to evaluate it at the following points (first column are the x-values and second column are the y-values) -

array([[-1.56113514,  4.51759732],        [-2.80261623,  5.068371  ],        [ 0.7792729 ,  6.0169462 ],        [-1.35672858,  3.52517478],        [-1.92074891,  5.79966161],        [-2.79340321,  4.73430001],        [-2.79655868,  5.05361163],        [-2.13637747,  5.39255837],        [ 0.17341809,  3.60918261],        [-1.22712921,  4.95327158]]) 

i.e. I would like to pass the function the first row of values and evaluate, then the second row and evaluate etc. and then the final result would be an array of the values evaluated at these points (so, an array consisting of 10 values).

So, for example, if the function was, say, a bivariate normal distribution -

def function2(x):  function2 = (mvnorm.pdf(x,[0,0],[[1,0],[0,1]]))  return function2 

and I passed the above values into this function, I would get -

array([  1.17738907e-05,   1.08383957e-04,   1.69855078e-04,          5.64757613e-06,   1.37432346e-05,   1.44032800e-04,          1.33426313e-05,   1.97822328e-06,   6.56121709e-08,          4.67076770e-05]) 

So basically, I am looking for a way to rewrite the function so that it can do this. Moreover, I would like to keep the function as a function of one variable only (i.e. only a function of x).

Thank you for your help!

like image 683
tattybojangler Avatar asked Aug 10 '17 04:08

tattybojangler


People also ask

What is Axis in NumPy array?

Axes are defined for arrays with more than one dimension. A 2-dimensional array has two corresponding axes: the first running vertically downwards across rows (axis 0), and the second running horizontally across columns (axis 1). Many operation can take place along one of these axes.

What does NumPy vectorize do?

The vectorized function evaluates pyfunc over successive tuples of the input arrays like the python map function, except it uses the broadcasting rules of numpy. The data type of the output of vectorized is determined by calling the function with the first element of the input.


2 Answers

You can use np.apply_along_axis:

np.apply_along_axis(function, 1, array) 

The first argument is the function, the second argument is the axis along which the function is to be applied. In your case, it is the first axis. The last argument is the array, of course.


You should be warned, however, that apply_along_axis is only a convenience function, not a magic bullet. It has a severe speed limitation, since it just hides a loop. You should always try to vectorize your computation, where possible. Here's how I'd do this:

v = array[:, 0] ** 2   # computing just once   return np.exp((-v / 200) - 0.5 * (array[:, 1] + 0.05 * v - 5) ** 2) 
like image 106
cs95 Avatar answered Oct 08 '22 09:10

cs95


There are several ways to accomplish this, the only line you have to change is the asignment of x and y. x,y = vector only works if the first dimension of vector has length 2. (vector.shape = 2,...). So you can simply change your vector with any of the following commands:

x,y = vector.T #transpose the array x,y = vector.swapaxes(0,1) #swap the axis 0 and 1 x,y = np.rollaxis(vector,1) #roll the axis 1 to the front x,y = vector[:,0], vector[:,1] #slice asignement 

Just choose the one you like most, there might be other ways (I'm almost sure, but I guess this will suffice). The last one is by far the fastest, the others are comparable. The disatvantage of the last one however is, that it's not so easy to use it in higher dimensions.

like image 42
Jürg Merlin Spaak Avatar answered Oct 08 '22 10:10

Jürg Merlin Spaak