I'm coding a function taking in an array of shape (2,) and performing a simple operation:
def simpfunc(x):
return x[1]-x[0]
I would now like to evaluate this function over a large quantity of values, created by a meshgrid. To this end, I apply the following (as I wish to avoid for loops):
newfunc=vectorize(simpfunc)
G=array(meshgrid(linspace(0,5,5),linspace(0,5,5))).T
The array G is a large matrix (or I suppose a tensor), where each individual entry is an array containing two values. I would like to evaluate simpfunc over these (2,) arrays, producing a matrix with the calculated values. So I do the following:
newfunc(G)# IndexError: invalid index to scalar variable.
I have previously used vectorize to evaluate a function over vectors, but now I suppose the matrix, along with the sub-matirces are giving me some trouble.
Any ideas?
CodePudding user response:
The problem here is that G
is a 3-dimensional array (shape 5,5,2), but you do not want vectorize
to iterate through all the dimensions, only the first two, to output a 2-dimensional array - where the input to your simpfunc
function is sub-array rather than a single element.
The documentation for np.vectorize
states that
The vectorize function is provided primarily for convenience, not for performance. The implementation is essentially a for loop.
This being the case, if it is not doing exactly what you want, I would suggest using an explicit for
loop to do what you want:
output = np.zeros(G.shape[:-1], dtype=G.dtype)
for indices, value in np.ndenumerate(output):
output[indices] = simpfunc(G[indices])
The solution generalizes to however many dimensions you want included in your output, by changing the -1
to some other number.
Note that np.ndenumerate
will generate a sequence of 2-tuples of indices, value
, where the indices
will be (0, 0)
, (0, 1)
, etc on successive iterations, and the value
is the corresponding value in the array (in fact here it is always zero, because we initialized output
using np.zeros
, and is not used, so you could use _
instead in place of value
for the variable name in this code if you prefer).
(By the way, in this specific case, you could implement the solution without a loop, just as G[:,:,1] - G[:,:,0]
, but I am assuming here that simpfunc
is just a simple example and that the real problem that you want to solve is not amenable to that sort of solution.)