Come posso verificare i valori NaN?


Risposte:


1282

math.isnan (x)

Restituisce Truese x è un NaN (non un numero) e in caso Falsecontrario.

>>> import math
>>> x = float('nan')
>>> math.isnan(x)
True

5
@ charlie-parker: in Python3, math.isnan fa ancora parte del modulo di matematica. docs.python.org/3/library/math.html#math.isnan . Usa numpy.isnan se lo desideri, questa risposta è solo un suggerimento.
Gimel,

2
@ SittingBull Vedi docs.python.org/3/library/functions.html#float "Se l'argomento è una stringa, dovrebbe contenere un numero decimale", oppure "Infinity" "inf" "nan"
gimel

35
è math.isnanpreferito np.isnan()?
TMWP

34
@TMWP probabilmente ... import numpyrichiede circa 15 MB di RAM, mentre import mathrichiede circa 0,2 MB
petrpulc,

9
@TMWP: se si utilizza NumPy, numpy.isnanè una scelta superiore, poiché gestisce gli array NumPy. Se non stai usando NumPy, non c'è alcun vantaggio nel prendere una dipendenza NumPy e passare il tempo a caricare NumPy solo per un controllo NaN (ma se stai scrivendo il tipo di codice che fa i controlli NaN, è probabile che dovresti usare NumPy).
user2357112 supporta Monica il

360

Il solito modo di testare una NaN è vedere se è uguale a se stesso:

def isNaN(num):
    return num != num

8
Avvertenza: citando il commento di Bear sotto "Per le persone bloccate con Python <= 2.5. Nan! = Nan non ha funzionato in modo affidabile. Ha usato invece il numpy." Detto questo, in realtà non l'ho mai visto fallire.
mavnn,

22
Sono sicuro che, dato il sovraccarico dell'operatore, ci sono molti modi per confondere questa funzione. vai con math.isnan ()
djsadinoff l'

4
Nelle specifiche 754 menzionate sopra, NaN == NaN dovrebbe sempre essere falso, sebbene non sia sempre implementato come tale. Non è possibile, è così che la matematica e / o intorpidito lo controllano comunque sotto il cofano?
Hari Ganesan,

Grazie . questo è anche 15-20 volte più veloce rispetto all'utilizzo di np.isnan se si esegue un'operazione su uno scalare
thomas.mac

5
Anche se funziona e, in una certa misura, ha senso, sono un essere umano con dei principi e dichiaro che questo è una stregoneria proibita. Si prega di usare math.isnan invece.
Gonzalo,

152

numpy.isnan(number)ti dice se lo è NaNo no.


3
Funziona anche in Python versione 2.7.
Michel Keijzers,

6
numpy.all(numpy.isnan(data_list))è utile anche se è necessario determinare se tutti gli elementi nell'elenco sono nan
Jay P.

3
Non è necessario NumPy:all(map(math.isnan, [float("nan")]*5))
sleblanc,

6
Quando questa risposta è stata scritta 6 anni fa, Python 2.5 era ancora di uso comune e math.isnan non faceva parte della libreria standard. Adesso spero davvero che non sia così in molti posti!
mavnn,

4
si noti che np.isnan () non gestisce il tipo decimal.Decimal (come molte funzioni di numpy). math.isnan () gestisce.
Comte

55

Ecco tre modi in cui è possibile testare una variabile è "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)}")

Produzione

It's pd.isna  : True
It's np.isnan  : True
It's math.isnan  : True

2
pd.isna (valore) ha salvato molti problemi! lavorare come un fascino!
abhishake,

1
ps.isna()risolve i miei problemi. Grazie!
Darthbhyrava il

32

ecco una risposta che funziona con:

  • Implementazioni NaN conformi allo standard IEEE 754
    • vale a dire: NaN di pitone: float('nan'), numpy.nan...
  • qualsiasi altro oggetto: stringa o altro (non genera eccezioni se rilevato)

Un NaN implementato secondo lo standard è l'unico valore per il quale il confronto delle disuguaglianze con se stesso dovrebbe restituire True:

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

E alcuni esempi:

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)}")

Produzione:

nan      : True
nan      : True
55       : False
'string' : False
<function <lambda> at 0x000000000927BF28> : False

1
Le serie che sto controllando sono stringhe con valori mancanti sono 'nans' (???), quindi questa soluzione funziona dove altri falliscono.
keithpjolley

numpy.nanè un normale floatoggetto Python , proprio come il tipo restituito da float('nan'). La maggior parte dei NaN che incontri in NumPy non sarà l' numpy.nanoggetto.
user2357112 supporta Monica il

numpy.nandefinisce il valore NaN propria nella libreria sottostante C . Non avvolge la NaN di Python. Ma ora sono entrambi conformi allo standard IEEE 754 in quanto si basano sull'API C99.
x0s

@ user2357112supportsMonica: Python e NaN intorpidito in realtà non si comportano allo stesso modo: float('nan') is float('nan')(non univoci) e np.nan is np.nan(unici)
x0s

@ x0s: non ha nulla a che fare con NumPy. np.nanè un oggetto specifico, mentre ogni float('nan')chiamata produce un nuovo oggetto. Se lo facessi nan = float('nan'), lo faresti nan is nananche tu . Se costruissi un vero NumPy NaN con qualcosa del genere np.float64('nan'), lo otterrai np.float64('nan') is not np.float64('nan')anche tu .
user2357112 supporta Monica il

28

In realtà mi sono appena imbattuto in questo, ma per me stava controllando nan, -inf o inf. Ho appena usato

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

Questo vale per i numeri, falso per nan e entrambi inf, e solleverà un'eccezione per cose come stringhe o altri tipi (che è probabilmente una buona cosa). Inoltre, ciò non richiede l'importazione di librerie come matematica o numpy (numpy è così dannatamente grande che raddoppia le dimensioni di qualsiasi applicazione compilata).


9
math.isfinitenon è stato introdotto fino a Python 3.2, quindi data la risposta di @DaveTheScientist è stata pubblicata nel 2012 non era esattamente "reinventare la ruota" - la soluzione è ancora
valida

22

math.isnan ()

o confronta il numero con se stesso. NaN è sempre! = NaN, altrimenti (ad es. Se è un numero) il confronto dovrebbe avere esito positivo.


6
Per le persone bloccate con Python <= 2.5. Nan! = Nan non ha funzionato in modo affidabile. Usato invece numpy.
Orso

16

Un altro metodo se sei bloccato su <2.6, non hai intorpidimento e non hai il supporto IEEE 754:

def isNaN(x):
    return str(x) == str(1e400*0)

12

Bene, ho inserito questo post, perché ho avuto alcuni problemi con la funzione:

math.isnan()

Ci sono problemi quando si esegue questo codice:

a = "hello"
math.isnan(a)

Solleva un'eccezione. La mia soluzione è quella di fare un altro controllo:

def is_nan(x):
    return isinstance(x, float) and math.isnan(x)

3
Probabilmente è stato sottoposto a downgrade perché isnan () prende un float, non una stringa. Non c'è niente di sbagliato nella funzione e i problemi sono solo nel suo tentativo di usarla. (Per quel particolare caso d'uso la sua soluzione è valida, ma non è una risposta a questa domanda.)
Peter Hansen

6
Fai attenzione a controllare i tipi in questo modo. Questo non funzionerà ad es. Per NaP di numpy.float32. Meglio usare un tentativo / tranne la costruzione: def is_nan(x): try: return math.isnan(x) except: return False
Rob

3
NaN non significa che un valore non sia un numero valido. Fa parte della rappresentazione in virgola mobile IEEE per specificare che un determinato risultato non è definito. es. 0 / 0. Pertanto, chiedere se "ciao" è nan non ha senso.
Brice M. Dempsey,

2
questo è meglio perché NaN può atterrare in qualsiasi elenco di stringhe, ints o float, quindi controllo utile
RAFIQ

Ho dovuto implementare esattamente questo per gestire le colonne di stringhe nei panda.
Cristian Garcia

7

Con Python <2.6 ho finito con

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

Questo funziona per me con Python 2.5.1 su una scatola di Solaris 5.9 e con Python 2.6.5 su Ubuntu 10


6
Questo non è troppo portatile, come a volte Windows lo chiama-1.#IND
Mike T

5

Sto ricevendo i dati da un servizio Web che invia NaNcome stringa 'Nan'. Ma potrebbero esserci anche altri tipi di stringhe nei miei dati, quindi un semplice float(value)potrebbe generare un'eccezione. Ho usato la seguente variante della risposta accettata:

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

Requisiti:

isnan('hello') == False
isnan('NaN') == True
isnan(100) == False
isnan(float('nan')) = True

1
oppuretry: int(value)
chwi,

@chwi quindi cosa dice il tuo suggerimento valuesull'essere NaNo no?
Mahdi,

Bene, essendo "non un numero", tutto ciò che non può essere trasmesso a un int immagino in realtà non è un numero e la dichiarazione di prova fallirà? Prova, restituisci vero, tranne restituisci falso.
chwi,

@chwi Bene, prendendo "non un numero" letteralmente, hai ragione, ma non è questo il punto. In effetti, sto cercando esattamente quale sia la semantica NaN(come in Python da cosa potresti ottenere float('inf') * 0), e quindi anche se la stringa 'Hello' non è un numero, ma non lo è NaNperché NaNè ancora un valore numerico!
Mahdi,

@chwi: hai ragione, se la gestione delle eccezioni è per un'eccezione specifica. Ma in questa risposta sono state gestite eccezioni generiche. Quindi non è necessario controllare int(value)per tutte le eccezioni, Falseverrà scritto.
Harsha Biyani,

3

Tutti i metodi per dire se la variabile è NaN o None:

Nessuno 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

Come rimuovere gli elementi NaN (float) da un elenco di tipi di dati misti

Se hai tipi misti in un iterabile, ecco una soluzione che non 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 valutazione del cortocircuito significa che isnannon verrà chiamato su valori che non sono di tipo 'float', come False and (…)valuta rapidamente Falsesenza dover valutare il lato destro.


1

In Python 3.6 il controllo di un valore stringa x math.isnan (x) e np.isnan (x) genera un errore. Quindi non posso verificare se il valore dato è NaN o no se non so in anticipo che è un numero. Quanto segue sembra risolvere questo problema

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

1

Sembra che controllando se è uguale a se stesso

x!=x

è il più veloce.

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

Per galleggiante di tipo nan

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

per stringhe in panda prendere pd.isnull:

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

la funzione come estrazione di funzionalità per 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

Cosa per questa riduzione?
Max Kleiner,

isnull restituisce true non solo per i valori NaN.
Boris,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.