Home > Software design >  "invalid index to scalar variable." when trying to evaluate a function taking an array of
"invalid index to scalar variable." when trying to evaluate a function taking an array of

Time:08-24

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

  • Related