¿Cómo puedo verificar los valores de NaN?

982

float('nan')da como resultado Nan (no es un número). Pero, ¿cómo lo compruebo? Debería ser muy fácil, pero no puedo encontrarlo.

Jack Ha
fuente
20
Para un poco de historia de NaN en Python, vea PEP 754. python.org/dev/peps/pep-0754
Craig McQueen

Respuestas:

1284

matemáticas.isnan (x)

Devuelve Truesi x es un NaN (no un número), y de lo Falsecontrario.

>>> import math
>>> x = float('nan')
>>> math.isnan(x)
True
gimel
fuente
55
@ charlie-parker: En Python3, math.isnan sigue siendo parte del módulo matemático. docs.python.org/3/library/math.html#math.isnan . Use numpy.isnan si lo desea, esta respuesta es solo una sugerencia.
gimel
2
@ SittingBull Consulte docs.python.org/3/library/functions.html#float "Si el argumento es una cadena, debe contener un número decimal" o "Infinito" "inf" "nan"
gimel
35
se math.isnanprefiere a np.isnan()?
TMWP
34
@TMWP posiblemente ... import numpytoma alrededor de 15 MB de RAM, mientras que import mathtoma unos 0,2 MB
petrpulc
99
@TMWP: si está usando NumPy, numpy.isnanes una opción superior, ya que maneja los arreglos NumPy. Si no está usando NumPy, no tiene ningún beneficio tomar una dependencia de NumPy y pasar el tiempo para cargar NumPy solo para un chequeo de NaN (pero si está escribiendo el tipo de código que hace los cheques de NaN, es probable que deba usar NumPy).
user2357112 es compatible con Monica
360

La forma habitual de probar un NaN es ver si es igual a sí mismo:

def isNaN(num):
    return num != num
Chris Jester-Young
fuente
8
Palabra de advertencia: citando el comentario de Bear a continuación "Para las personas atrapadas con python <= 2.5. Nan! = Nan no funcionó de manera confiable. En su lugar, usó numpy". Dicho esto, en realidad nunca lo he visto fallar.
mavnn
22
Estoy seguro de que, dada la sobrecarga del operador, hay muchas maneras en que podría confundir esta función. ir con math.isnan ()
djsadinoff
44
Dice en la especificación 754 mencionada anteriormente que NaN == NaN siempre debe ser falso, aunque no siempre se implementa como tal. ¿No es posible que así es como las matemáticas y / o numpy verifican esto debajo del capó de todos modos?
Hari Ganesan
Gracias . esto también es 15-20 veces más rápido que usar np.isnan si se realiza una operación en un escalar
thomas.mac
55
Aunque esto funciona y, hasta cierto punto, tiene sentido, soy un humano con principios y por la presente declaro que esto es una brujería prohibida. Por favor utiliza math.isnan en lugar.
Gonzalo
152

numpy.isnan(number)te dice si es NaNo no.

mavnn
fuente
3
Funciona en python versión 2.7 también.
Michel Keijzers
66
numpy.all(numpy.isnan(data_list))también es útil si necesita determinar si todos los elementos de la lista son nan
Jay P.
3
No hay necesidad de NumPy:all(map(math.isnan, [float("nan")]*5))
sleblanc
66
Cuando esta respuesta se escribió hace 6 años, Python 2.5 todavía era de uso común, y math.isnan no era parte de la biblioteca estándar. ¡Hoy en día realmente espero que ese no sea el caso en muchos lugares!
mavnn
44
tenga en cuenta que np.isnan () no maneja el tipo decimal. Decimal (como muchas funciones de numpy). Math.isnan () maneja.
comte
55

Aquí hay tres formas en las que puede probar que una variable sea "NaN" o no.

import pandas as pd
import numpy as np
import math

#For single variable all three libraries return single boolean
x1 = float("nan")

print(f"It's pd.isna  : {pd.isna(x1)}")
print(f"It's np.isnan  : {np.isnan(x1)}")
print(f"It's math.isnan : {math.isnan(x1)}")

Salida

It's pd.isna  : True
It's np.isnan  : True
It's math.isnan  : True
M. Hamza Rajput
fuente
2
¡pd.isna (valor) ahorró muchos problemas! trabajando como un encanto!
abhishake
1
ps.isna()resuelve mis problemas ¡Gracias!
Darthbhyrava
32

Aquí hay una respuesta trabajando con:

  • Implementaciones NaN respetando el estándar IEEE 754
    • es decir: NaN de pitón: float('nan'), numpy.nan...
  • cualquier otro objeto: cadena o lo que sea (no genera excepciones si se encuentra)

Un NaN implementado siguiendo el estándar es el único valor para el cual la comparación de desigualdad consigo misma debería devolver True:

def is_nan(x):
    return (x != x)

Y algunos ejemplos:

import numpy as np
values = [float('nan'), np.nan, 55, "string", lambda x : x]
for value in values:
    print(f"{repr(value):<8} : {is_nan(value)}")

Salida:

nan      : True
nan      : True
55       : False
'string' : False
<function <lambda> at 0x000000000927BF28> : False
x0s
fuente
1
La serie que estoy comprobando es cadenas con valores faltantes son 'nans' (???), por lo que esta solución funciona donde otros fallaron.
keithpjolley
numpy.nanes un floatobjeto Python normal , al igual que el tipo devuelto por float('nan'). La mayoría de los NaN que encuentres en NumPy no serán el numpy.nanobjeto.
user2357112 es compatible con Monica
numpy.nandefine su valor NaN por sí solo en la biblioteca subyacente en C . No envuelve el NaN de Python. Pero ahora, ambos cumplen con el estándar IEEE 754 ya que confían en la API C99.
x0s
@ user2357112supportsMonica: Python y NaN numpy en realidad no se comportan de la misma manera: float('nan') is float('nan')(no único) y np.nan is np.nan(único)
x0s
@ x0s: Eso no tiene nada que ver con NumPy. np.nanes un objeto específico, mientras que cada float('nan')llamada produce un nuevo objeto. Si lo nan = float('nan')hicieras, entonces también lo conseguirías nan is nan. Si has construido un real NumPy NaN con algo así como np.float64('nan'), a continuación, se obtendría np.float64('nan') is not np.float64('nan')demasiado .
user2357112 es compatible con Monica el
28

De hecho, me encontré con esto, pero para mí estaba buscando nan, -inf o inf. Acabo de usar

if float('-inf') < float(num) < float('inf'):

Esto es cierto para los números, falso para nan y ambos inf, y generará una excepción para cosas como cadenas u otros tipos (que probablemente sea algo bueno). Además, esto no requiere importar ninguna biblioteca como matemática o numpy (numpy es tan grande que duplica el tamaño de cualquier aplicación compilada).

DaveTheScientist
fuente
99
math.isfiniteno se introdujo hasta Python 3.2, por lo que, dada la respuesta de @DaveTheScientist publicada en 2012, no fue exactamente "reinventar [la rueda]" - la solución sigue siendo
válida
22

math.isnan ()

o compara el número consigo mismo. NaN es siempre! = NaN, de lo contrario (por ejemplo, si es un número) la comparación debería tener éxito.

Tomalak
fuente
66
Para personas atrapadas con python <= 2.5. Nan! = Nan no funcionó de manera confiable. Usado numpy en su lugar.
Oso
16

Otro método si está atascado en <2.6, no tiene numpy y no tiene soporte IEEE 754:

def isNaN(x):
    return str(x) == str(1e400*0)
Josh Lee
fuente
12

Bueno, entré en esta publicación, porque he tenido algunos problemas con la función:

math.isnan()

Hay un problema cuando ejecuta este código:

a = "hello"
math.isnan(a)

Se plantea una excepción. Mi solución para eso es hacer otra verificación:

def is_nan(x):
    return isinstance(x, float) and math.isnan(x)
Idok
fuente
3
Probablemente fue rechazado porque isnan () toma un flotante, no una cadena. No hay nada de malo en la función, y los problemas están solo en su intento de usarla. (Para ese caso de uso particular, su solución es válida, pero no es una respuesta a esta pregunta).
Peter Hansen
66
Tenga cuidado al verificar los tipos de esta manera. Esto no funcionará, por ejemplo, para numpy.float32 NaN's. Mejor usar una prueba / excepto construcción: def is_nan(x): try: return math.isnan(x) except: return False
Rob
3
NaN no significa que un valor no sea un número válido. Es parte de la representación de punto flotante IEEE para especificar que un resultado particular no está definido. por ejemplo, 0 / 0. Por lo tanto, preguntar si "hola" es nan no tiene sentido.
Brice M. Dempsey
2
esto es mejor porque NaN puede aterrizar en cualquier lista de cadenas, ints o flotantes, por lo que es útil verificar
RAFIQ
Tuve que implementar exactamente esto para manejar columnas de cadena en pandas.
Cristian Garcia
7

Con python <2.6 terminé con

def isNaN(x):
    return str(float(x)).lower() == 'nan'

Esto funciona para mí con python 2.5.1 en un cuadro de Solaris 5.9 y con python 2.6.5 en Ubuntu 10

Mauro Bianchi
fuente
66
Esto no es demasiado portátil, ya que Windows a veces lo llama así-1.#IND
Mike T
5

Estoy recibiendo los datos de un servicio web que se envía NaNcomo una cadena 'Nan'. Pero también podría haber otros tipos de cadenas en mis datos, por lo que un simple float(value)podría arrojar una excepción. Usé la siguiente variante de la respuesta aceptada:

def isnan(value):
  try:
      import math
      return math.isnan(float(value))
  except:
      return False

Requisito:

isnan('hello') == False
isnan('NaN') == True
isnan(100) == False
isnan(float('nan')) = True
Mahdi
fuente
1
otry: int(value)
chwi
@chwi, entonces, ¿qué dice tu sugerencia sobre valueser NaNo no?
Mahdi
Bueno, al ser "no un número", cualquier cosa que no se pueda emitir a un int, supongo que en realidad no es un número, y la declaración de prueba fallará. Intenta, devuelve verdadero, excepto devuelve falso.
chwi
@chwi Bueno, tomando "no un número" literalmente, tienes razón, pero ese no es el punto aquí. De hecho, estoy buscando exactamente cuál es la semántica de NaN(como en Python de lo que podría obtener float('inf') * 0), y por lo tanto, aunque la cadena 'Hola' no es un número, ¡pero tampoco lo es NaNporque NaNtodavía es un valor numérico!
Mahdi
@chwi: Tiene razón, si el manejo de excepciones es para una excepción específica. Pero en esta respuesta, se han manejado excepciones genéricas. Por lo tanto, no es necesario verificar int(value)Para todas las excepciones, Falsese escribirá.
Harsha Biyani
3

Todos los métodos para saber si la variable es NaN o Ninguna:

Ninguno tipo

In [1]: from numpy import math

In [2]: a = None
In [3]: not a
Out[3]: True

In [4]: len(a or ()) == 0
Out[4]: True

In [5]: a == None
Out[5]: True

In [6]: a is None
Out[6]: True

In [7]: a != a
Out[7]: False

In [9]: math.isnan(a)
Traceback (most recent call last):
  File "<ipython-input-9-6d4d8c26d370>", line 1, in <module>
    math.isnan(a)
TypeError: a float is required

In [10]: len(a) == 0
Traceback (most recent call last):
  File "<ipython-input-10-65b72372873e>", line 1, in <module>
    len(a) == 0
TypeError: object of type 'NoneType' has no len()

Tipo NaN

In [11]: b = float('nan')
In [12]: b
Out[12]: nan

In [13]: not b
Out[13]: False

In [14]: b != b
Out[14]: True

In [15]: math.isnan(b)
Out[15]: True
siberiawolf61
fuente
2

Cómo eliminar los elementos NaN (flotantes) de una lista de tipos de datos mixtos

Si tiene tipos mixtos en un iterable, aquí hay una solución que no usa numpy:

from math import isnan

Z = ['a','b', float('NaN'), 'd', float('1.1024')]

[x for x in Z if not (
                      type(x) == float # let's drop all float values…
                      and isnan(x) # … but only if they are nan
                      )]
['a', 'b', 'd', 1.1024]

La evaluación de cortocircuito significa que isnanno se invocará en valores que no sean del tipo 'flotante', como False and (…)se evalúa rápidamente Falsesin tener que evaluar el lado derecho.

sleblanc
fuente
1

En Python 3.6, verificar un valor de cadena x math.isnan (x) y np.isnan (x) genera un error. Por lo tanto, no puedo verificar si el valor dado es NaN o no si no sé de antemano que es un número. Lo siguiente parece resolver este problema

if str(x)=='nan' and type(x)!='str':
    print ('NaN')
else:
    print ('non NaN')
Valentin Goikhman
fuente
1

Parece que comprobar si es igual a sí mismo

x!=x

Es el más rápido.

import pandas as pd 
import numpy as np 
import math 

x = float('nan')

%timeit x!=x                                                                                                                                                                                                                        
44.8 ns ± 0.152 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

%timeit math.isnan(x)                                                                                                                                                                                                               
94.2 ns ± 0.955 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

%timeit pd.isna(x) 
281 ns ± 5.48 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

%timeit np.isnan(x)                                                                                                                                                                                                                 
1.38 µs ± 15.7 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
Grzegorz
fuente
0

Para nan de tipo flotante

>>> import pandas as pd
>>> value = float(nan)
>>> type(value)
>>> <class 'float'>
>>> pd.isnull(value)
True
>>>
>>> value = 'nan'
>>> type(value)
>>> <class 'str'>
>>> pd.isnull(value)
False
J11
fuente
-5

para cadenas en panda tome pd.isnull:

if not pd.isnull(atext):
  for word in nltk.word_tokenize(atext):

la función como extracción de características para NLTK

def act_features(atext):
features = {}
if not pd.isnull(atext):
  for word in nltk.word_tokenize(atext):
    if word not in default_stopwords:
      features['cont({})'.format(word.lower())]=True
return features
Max Kleiner
fuente
¿Qué hay para esta reducción?
Max Kleiner el
isnull devuelve verdadero no solo para los valores NaN.
Boris