numpy vectorize multidimensional function
As mentioned in the notes for vectorize
:
The vectorize function is provided primarily for convenience, not for performance. The implementation is essentially a for loop.
So while vectorizing your code may be a good idea via numpy
types and functions, you probably shouldn't do this using numpy.vectorize
.
For the example you gave, your cost
might be simply and efficiently calculated as a function operating on a numpy
array:
def cost(x): # Create the empty output output = np.empty(x.shape) # Select the first group using a boolean array group1 = (0 < x) & (x < 15) output[group1] = np.sin(x[group1])*x[group1] # Select second group as inverse (logical not) of group1 output[~group1] = 15 + np.min( [np.abs(x[~group1]-0), np.abs(x[~group1]-15)], axis=0) return output
np.vectorize
feeds scalars to your function. For example:
In [1090]: def _cost(u): ...: return u*2In [1092]: cost=np.vectorize(_cost)In [1093]: cost(np.arange(10) ...: )Out[1093]: array([ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18])In [1094]: cost(np.ones((3,4)))Out[1094]: array([[ 2., 2., 2., 2.], [ 2., 2., 2., 2.], [ 2., 2., 2., 2.]])
But your function acts as though it is getting a list or array with 2 values. What were you intending?
A function with 2 scalars:
In [1095]: def _cost(u,v): ...: return u+v ...: ...: In [1096]: cost=np.vectorize(_cost)In [1098]: cost(np.arange(3),np.arange(3,6))Out[1098]: array([3, 5, 7])In [1099]: cost([[1],[2]],np.arange(3,6))Out[1099]: array([[4, 5, 6], [5, 6, 7]])
Or with your 2 column x
:
In [1103]: cost(x[:,0],x[:,1])Out[1103]: array([-1.7291913 , -0.46343403, 0.61574928, 0.9864683 , -1.22373097, 1.01970917, 0.22862683, -0.11653917, -1.18319723, -3.39580376])
which is the same as doing an array sum on axis 1
In [1104]: x.sum(axis=1)Out[1104]: array([-1.7291913 , -0.46343403, 0.61574928, 0.9864683 , -1.22373097, 1.01970917, 0.22862683, -0.11653917, -1.18319723, -3.39580376])