spec3
spec3

Reputation: 501

how to handle nan in functions that should be used both for numpy and scalars?

I'm defining a function that I want to use both for numpy arrays and for scalars.

def inv(x):
    return 1/x

this gives back inf in numpy arrays

A = np.zeros([4,4])
inv(A)
array([[ inf,  inf,  inf,  inf],
       [ inf,  inf,  inf,  inf],
       [ inf,  inf,  inf,  inf],
       [ inf,  inf,  inf,  inf]])

and errors with a scalar

inv(0.0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in inv
ZeroDivisionError: float division by zero

To detect these zero values I can use numpy.where for numpy arrays and if(a==0) for scalars.

Do you know a way to write this that is good for both numpy arrays and scalars?

Thanks

GB

Upvotes: 0

Views: 112

Answers (2)

Stop harming Monica
Stop harming Monica

Reputation: 12618

Use asanyarray to convert the parameter:

>>> def inv(x):
...     return 1 / np.asanyarray(x)
... 
>>> inv(0)
inf
>>> inv([0])
array([ inf])

Upvotes: 1

Benjamin
Benjamin

Reputation: 11860

0.0 is not a numpy scalar, it is a Python float. Feed it a real numpy scalar: numpy.float_(0.) (or your prefered float type) and it will work as expected.

Note that numpy.float_, numpy.float16, numpy.float32, etc. are different from numpy.float(), which is equivalent to Python's float() (as pointed out by @dawg).

Inspect both with type to reveal the issue:

type(0.0)
>>> <class 'float'>
type(numpy.float_(0.0))
>>> <class 'numpy.float64'>

numpy.float == float
>>> True

More details here: https://docs.scipy.org/doc/numpy-1.10.1/reference/arrays.scalars.html, note the key statement:

Array scalars have the same attributes and methods as ndarrays

Upvotes: 1

Related Questions