¿Cómo puedo verificar los valores de NaN?


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

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

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.


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

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

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


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.


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)

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)

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


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

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

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.


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

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)

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

-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

¿Qué hay para esta reducción?
Max Kleiner el

isnull devuelve verdadero no solo para los valores NaN.
Boris
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.