0

I have an ndarray A that stores objects of the same type, in particular various LinearNDInterpolator objects. For example's sake assume it's just 2:

>>> A
array([ <scipy.interpolate.interpnd.LinearNDInterpolator object at 0x7fe122adc750>,
       <scipy.interpolate.interpnd.LinearNDInterpolator object at 0x7fe11daee590>], dtype=object)

I want to be able to do two things. First, I'd like to evaluate all objects in A at a certain point and get back an ndarray of A.shape with all the values in it. Something like

>> A[[0,1]](1,1) = 
array([ 1, 2])

However, I get

TypeError: 'numpy.ndarray' object is not callable

Is it possible to do that?

Second, I would like to change the interpolation values without constructing new LinearNDInterpolator objects (since the nodes stay the same). I.e., something like

A[[0,1]].values = B

where B is an ndarray containing the new values for every element of A.

Thank you for your suggestions.

Tobias
  • 514
  • 6
  • 17

1 Answers1

1

The same issue, but with simpler functions:

In [221]: A=np.array([add,multiply])

In [222]: A[0](1,2)  # individual elements can be called
Out[222]: 3

In [223]: A(1,2)    # but not the array as a whole
---------------------------------------------------------------------------    
TypeError: 'numpy.ndarray' object is not callable 

We can iterate over a list of functions, or that array as well, calling each element on the parameters. Done right we can even zip a list of functions and a list of parameters.

In [224]: ll=[add,multiply]

In [225]: [x(1,2) for x in ll]
Out[225]: [3, 2]

In [226]: [x(1,2) for x in A]
Out[226]: [3, 2]

Another test, the callable function:

In [229]: callable(A)
Out[229]: False

In [230]: callable(A[0])
Out[230]: True

Can you change the interpolation values for individual Interpolators? If so, just iterate through the list and do that.

In general, dtype object arrays function like lists. They contain the same kind of object pointers. Most operations requires the same sort of iteration. Unless you need to organize the elements in multiple dimensions, dtype object arrays have few, if any advantages over lists.

Another thought - the normal array dtype is numeric or fixed length strings. These elements are not callable, so there's no need to implement a .__call__ method on these arrays. They could write something like that to operate on object dtype arrays, but the core action is a Python call. So such a function would just hide the kind of iteration that I outlined.

In another recent question I showed how to use np.char.upper to apply a string method to every element of a S dtype array. But my time tests showed that this did not speedup anything.

hpaulj
  • 221,503
  • 14
  • 230
  • 353
  • Hey, thanks for your answer. The issue is that the array is n-dimensional, so it would be tedious to work with lists or loops. I managed to get the first thing done using numpy.frompyfunc: I can define eval_element = lambda array: array(1,1) and then define eval_ufunc = np.frompyfunc(eval_element, 1, 1). eval_ufunc(A) then gives back an ndarray of each LinearNDinterpolator evalutated at (1,1). – Tobias Apr 13 '16 at 10:09
  • And yes, you can change the values of the Interpolators, they are stored in the A[0].values attribute. – Tobias Apr 13 '16 at 13:46
  • `frompyfunc` is under appreciated. I've used it in a few SO answers, eg. http://stackoverflow.com/a/36297194/901925 – hpaulj Apr 13 '16 at 16:46