Is it possible to set an element of an array to NaN
in Python?
Additionally, is it possible to set a variable to +/- infinity? If so, is there any funct
Cast from string using float()
:
>>> float('NaN')
nan
>>> float('Inf')
inf
>>> -float('Inf')
-inf
>>> float('Inf') == float('Inf')
True
>>> float('Inf') == 1
False
Yes, you can use numpy for that.
import numpy as np
a = arange(3,dtype=float)
a[0] = np.nan
a[1] = np.inf
a[2] = -np.inf
a # is now [nan,inf,-inf]
np.isnan(a[0]) # True
np.isinf(a[1]) # True
np.isinf(a[2]) # True
Is it possible to set a number to NaN or infinity?
Yes, in fact there are several ways. A few work without any imports, while others require import
, however for this answer I'll limit the libraries in the overview to standard-library and NumPy (which isn't standard-library but a very common third-party library).
The following table summarizes the ways how one can create a not-a-number or a positive or negative infinity float
:
╒══════════╤══════════════╤════════════════════╤════════════════════╕
│ result │ NaN │ Infinity │ -Infinity │
│ module │ │ │ │
╞══════════╪══════════════╪════════════════════╪════════════════════╡
│ built-in │ float("nan") │ float("inf") │ -float("inf") │
│ │ │ float("infinity") │ -float("infinity") │
│ │ │ float("+inf") │ float("-inf") │
│ │ │ float("+infinity") │ float("-infinity") │
├──────────┼──────────────┼────────────────────┼────────────────────┤
│ math │ math.nan │ math.inf │ -math.inf │
├──────────┼──────────────┼────────────────────┼────────────────────┤
│ cmath │ cmath.nan │ cmath.inf │ -cmath.inf │
├──────────┼──────────────┼────────────────────┼────────────────────┤
│ numpy │ numpy.nan │ numpy.PINF │ numpy.NINF │
│ │ numpy.NaN │ numpy.inf │ -numpy.inf │
│ │ numpy.NAN │ numpy.infty │ -numpy.infty │
│ │ │ numpy.Inf │ -numpy.Inf │
│ │ │ numpy.Infinity │ -numpy.Infinity │
╘══════════╧══════════════╧════════════════════╧════════════════════╛
A couple remarks to the table:
float
constructor is actually case-insensitive, so you can also use float("NaN")
or float("InFiNiTy")
. cmath
and numpy
constants return plain Python float
objects.numpy.NINF
is actually the only constant I know of that doesn't require the -
.It is possible to create complex NaN and Infinity with complex
and cmath
:
╒══════════╤════════════════╤═════════════════╤═════════════════════╤══════════════════════╕
│ result │ NaN+0j │ 0+NaNj │ Inf+0j │ 0+Infj │
│ module │ │ │ │ │
╞══════════╪════════════════╪═════════════════╪═════════════════════╪══════════════════════╡
│ built-in │ complex("nan") │ complex("nanj") │ complex("inf") │ complex("infj") │
│ │ │ │ complex("infinity") │ complex("infinityj") │
├──────────┼────────────────┼─────────────────┼─────────────────────┼──────────────────────┤
│ cmath │ cmath.nan ¹ │ cmath.nanj │ cmath.inf ¹ │ cmath.infj │
╘══════════╧════════════════╧═════════════════╧═════════════════════╧══════════════════════╛
The options with ¹ return a plain float
, not a complex
.
is there any function to check whether a number is infinity or not?
Yes there is - in fact there are several functions for NaN, Infinity, and neither Nan nor Inf. However these predefined functions are not built-in, they always require an import
:
╒══════════╤═════════════╤════════════════╤════════════════════╕
│ for │ NaN │ Infinity or │ not NaN and │
│ │ │ -Infinity │ not Infinity and │
│ module │ │ │ not -Infinity │
╞══════════╪═════════════╪════════════════╪════════════════════╡
│ math │ math.isnan │ math.isinf │ math.isfinite │
├──────────┼─────────────┼────────────────┼────────────────────┤
│ cmath │ cmath.isnan │ cmath.isinf │ cmath.isfinite │
├──────────┼─────────────┼────────────────┼────────────────────┤
│ numpy │ numpy.isnan │ numpy.isinf │ numpy.isfinite │
╘══════════╧═════════════╧════════════════╧════════════════════╛
Again a couple of remarks:
cmath
and numpy
functions also work for complex objects, they will check if either real or imaginary part is NaN or Infinity.numpy
functions also work for numpy
arrays and everything that can be converted to one (like lists, tuple, etc.)numpy.isposinf
and numpy.isneginf
.NaN
: pandas.isna and pandas.isnull (but not only NaN, it matches also None
and NaT
)Even though there are no built-in functions, it would be easy to create them yourself (I neglected type checking and documentation here):
def isnan(value):
return value != value # NaN is not equal to anything, not even itself
infinity = float("infinity")
def isinf(value):
return abs(value) == infinity
def isfinite(value):
return not (isnan(value) or isinf(value))
To summarize the expected results for these functions (assuming the input is a float):
╒════════════════╤═══════╤════════════╤═════════════╤══════════════════╕
│ input │ NaN │ Infinity │ -Infinity │ something else │
│ function │ │ │ │ │
╞════════════════╪═══════╪════════════╪═════════════╪══════════════════╡
│ isnan │ True │ False │ False │ False │
├────────────────┼───────┼────────────┼─────────────┼──────────────────┤
│ isinf │ False │ True │ True │ False │
├────────────────┼───────┼────────────┼─────────────┼──────────────────┤
│ isfinite │ False │ False │ False │ True │
╘════════════════╧═══════╧════════════╧═════════════╧══════════════════╛
Is it possible to set an element of an array to NaN in Python?
In a list it's no problem, you can always include NaN (or Infinity) there:
>>> [math.nan, math.inf, -math.inf, 1] # python list
[nan, inf, -inf, 1]
However if you want to include it in an array
(for example array.array
or numpy.array
) then the type of the array must be float
or complex
because otherwise it will try to downcast it to the arrays type!
>>> import numpy as np
>>> float_numpy_array = np.array([0., 0., 0.], dtype=float)
>>> float_numpy_array[0] = float("nan")
>>> float_numpy_array
array([nan, 0., 0.])
>>> import array
>>> float_array = array.array('d', [0, 0, 0])
>>> float_array[0] = float("nan")
>>> float_array
array('d', [nan, 0.0, 0.0])
>>> integer_numpy_array = np.array([0, 0, 0], dtype=int)
>>> integer_numpy_array[0] = float("nan")
ValueError: cannot convert float NaN to integer
When using Python 2.4, try
inf = float("9e999")
nan = inf - inf
I am facing the issue when I was porting the simplejson to an embedded device which running the Python 2.4, float("9e999")
fixed it. Don't use inf = 9e999
, you need convert it from string.
-inf
gives the -Infinity
.