Jak mogę sprawdzić wartości NaN?


Odpowiedzi:


1275

math.isnan (x)

Zwraca, Truejeśli x jest NaN (nie liczbą) i w Falseprzeciwnym razie.

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

5
@ charlie-parker: W Python3 math.isnan jest nadal częścią modułu matematycznego. docs.python.org/3/library/math.html#math.isnan . Jeśli chcesz, użyj numpy.isnan, ta odpowiedź to tylko sugestia.
gimel

2
@ SittingBull Patrz docs.python.org/3/library/functions.html#float "Jeśli argument jest łańcuchem, powinien zawierać liczbę dziesiętną" lub "Infinity" "inf" "nan"
gimel

35
jest math.isnanpreferowany np.isnan()?
TMWP

34
@ TMWP prawdopodobnie ... import numpyzajmuje około 15 MB pamięci RAM, podczas gdy import mathzajmuje około 0,2 MB
petrpulc

9
@TMWP: Jeśli używasz NumPy, numpy.isnanjest lepszym wyborem, ponieważ obsługuje tablice NumPy. Jeśli nie używasz NumPy, przyjmowanie zależności NumPy i poświęcanie czasu na ładowanie NumPy tylko na czek NaN nie jest korzystne (ale jeśli piszesz rodzaj kodu, który wykonuje kontrole NaN, prawdopodobnie powinieneś użyć NumPy).
user2357112 obsługuje Monikę

359

Zwykłym sposobem na sprawdzenie NaN jest sprawdzenie, czy jest on równy:

def isNaN(num):
    return num != num

8
Słowo ostrzeżenia: cytując komentarz Niedźwiedzia poniżej „Dla ludzi, którzy utknęli w python <= 2.5. Nan! = Nan nie działał niezawodnie. Zamiast tego użyłem numpy.” Powiedziawszy to, nigdy tak naprawdę nie widziałem, żeby zawiodła.
mavnn

22
Jestem pewien, że biorąc pod uwagę przeciążenie operatora, istnieje wiele sposobów na pomylenie tej funkcji. idź z math.isnan ()
djsadinoff,

4
W powyższej specyfikacji 754 jest powiedziane, że NaN == NaN zawsze powinien być fałszywy, chociaż nie zawsze jest zaimplementowany jako taki. Czy nie jest możliwe, w ten sposób matematyka i / lub numpy sprawdza to pod maską?
Hari Ganesan

Dzięki . jest to również 15-20 razy szybsze niż użycie np.isnan, jeśli wykonujesz operację na skalar
thomas.mac

5
Mimo, że to działa i do pewnego stopnia ma sens, jestem człowiekiem z zasadami i niniejszym oświadczam, że jest to zabronione czary. Zamiast tego użyj math.isnan.
Gonzalo

152

numpy.isnan(number)powie ci, czy to jest NaNczy nie.


3
Działa również w Pythonie w wersji 2.7.
Michel Keijzers,

6
numpy.all(numpy.isnan(data_list))przydaje się również, gdy trzeba ustalić, czy wszystkie elementy na liście są nan
Jay P.

3
Nie ma potrzeby korzystania z NumPy:all(map(math.isnan, [float("nan")]*5))
sleblanc

6
Kiedy ta odpowiedź została napisana 6 lat temu, Python 2.5 był nadal w powszechnym użyciu - a math.isnan nie był częścią standardowej biblioteki. Teraz mam nadzieję, że w wielu miejscach tak nie jest!
mavnn

4
zwróć uwagę, że np.isnan () nie obsługuje decimal.Decimal typu (tylu funkcji numpy). math.isnan () obsługuje.
kometa

55

Oto trzy sposoby testowania zmiennej na „NaN” lub nie.

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

Wynik

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

2
pd.isna (wartość) zaoszczędził wiele problemów! działa jak urok!
abhishake

1
ps.isna()rozwiązuje moje problemy. Dzięki!
darthbhyrava

32

oto odpowiedź współpracująca z:

  • Implementacje NaN zgodne ze standardem IEEE 754
    • tj .: NaN: python float('nan'), numpy.nan...
  • wszelkie inne obiekty: ciąg znaków lub cokolwiek innego (nie stwarza wyjątków, jeśli zostaną napotkane)

NaN zaimplementowany zgodnie ze standardem jest jedyną wartością, dla której porównanie nierówności z samym sobą powinno zwrócić True:

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

I kilka przykładów:

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

Wynik:

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

1
Seria, którą sprawdzam, to ciągi z brakującymi wartościami to „nans” (???), więc to rozwiązanie działa tam, gdzie inne zawiodły.
keithpjolley,

numpy.nanjest zwykłym floatobiektem Pythona , podobnie jak ten zwracany przez float('nan'). Większość NaN, które spotkasz w NumPy, nie będzie numpy.nanobiektem.
user2357112 obsługuje Monikę

numpy.nanokreśla jej wartość NaN na własną rękę w podstawowej biblioteki w C . Nie zawija NaN Pythona. Ale teraz oba są zgodne ze standardem IEEE 754, ponieważ polegają na API C99.
x0s

@ user2357112supportsMonica: Python i numpy NaN faktycznie nie zachowują się w ten sam sposób: float('nan') is float('nan')(nie-unikalny) i np.nan is np.nan(unikalny)
x0s

@ x0s: To nie ma nic wspólnego z NumPy. np.nanjest konkretnym obiektem, a każde float('nan')wywołanie tworzy nowy obiekt. Gdybyś to zrobił nan = float('nan'), ty też byś to dostał nan is nan. Jeśli skonstruował rzeczywistą NumPy NaN z czymś takim np.float64('nan'), to można dostać np.float64('nan') is not np.float64('nan')zbyt .
user2357112 obsługuje Monikę

28

Właściwie to po prostu na to wpadłem, ale dla mnie sprawdzało to nan, inf lub inf. Właśnie użyłem

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

Dotyczy to liczb, fałszu dla nan i obu inf, i spowoduje wyjątek dla takich rzeczy jak ciągi znaków lub inne typy (co jest prawdopodobnie dobrą rzeczą). Nie wymaga to również importowania bibliotek takich jak matematyka czy numpy (numpy jest tak cholernie duże, że podwaja rozmiar każdej skompilowanej aplikacji).


9
math.isfinitezostał wprowadzony dopiero w Pythonie 3.2, więc biorąc pod uwagę odpowiedź @DaveTheScientist opublikowano w 2012 roku, nie było to dokładnie „wynaleźć koło” - rozwiązanie nadal dotyczy osób pracujących z Pythonem 2.
sudo_coffee

22

math.isnan ()

lub porównaj liczbę z samym sobą. NaN jest zawsze! = NaN, w przeciwnym razie (np. Jeśli jest to liczba) porównanie powinno się powieść.


6
Dla osób, które utknęły z pythonem <= 2,5. Nan! = Nan nie działał niezawodnie. Zamiast tego użyto numpy.
Niedźwiedź

16

Inna metoda, jeśli utkniesz na <2.6, nie masz numpy i nie masz obsługi IEEE 754:

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

11

Wpisałem ten post, ponieważ miałem pewne problemy z funkcją:

math.isnan()

Występuje problem po uruchomieniu tego kodu:

a = "hello"
math.isnan(a)

Rodzi wyjątek. Moim rozwiązaniem jest ponowne sprawdzenie:

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

3
Prawdopodobnie zostało to zanegowane, ponieważ isnan () przyjmuje liczbę zmiennoprzecinkową, a nie ciąg znaków. Nie ma nic złego w tej funkcji, a problemy dotyczą tylko jego próby użycia. (W tym konkretnym przypadku użycia jego rozwiązanie jest poprawne, ale nie jest to odpowiedź na to pytanie.)
Peter Hansen

6
Ostrożnie sprawdzaj typy w ten sposób. To nie zadziała np. Dla numpy.float32 NaN. Lepiej użyć konstrukcji try / try: def is_nan(x): try: return math.isnan(x) except: return False
Rob

3
NaN nie oznacza, że ​​wartość nie jest poprawną liczbą. Częścią reprezentacji zmiennoprzecinkowej IEEE jest określenie, że określony wynik jest niezdefiniowany. np. 0 / 0. Dlatego pytanie, czy „cześć” jest nan, jest bez znaczenia.
Brice M. Dempsey,

2
jest to lepsze, ponieważ NaN może wylądować na dowolnej liście ciągów, liczb całkowitych lub liczb
zmiennoprzecinkowych

8

Z pythonem <2.6 skończyłem z

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

Działa to dla mnie z Pythonem 2.5.1 na pudełku Solaris 5.9 iz Pythonem 2.6.5 na Ubuntu 10


6
Nie jest to zbyt przenośne, jak to czasem nazywa Windows-1.#IND
Mike T

5

Otrzymuję dane z usługi internetowej, która wysyła NaNjako ciąg znaków 'Nan'. Ale w moich danych mogą znajdować się również inne rodzaje ciągów, więc prosty float(value)może zgłosić wyjątek. Użyłem następującego wariantu zaakceptowanej odpowiedzi:

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

Wymaganie:

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

1
lubtry: int(value)
chwi

@chwi, więc co twoja sugestia mówi o valuebyciu NaNczy nie?
Mahdi

Cóż, będąc „nie liczbą”, cokolwiek, co nie może być przypisane do liczby int, myślę, że w rzeczywistości nie jest liczbą, a instrukcja try zawiedzie? Spróbuj zwrócić true, z wyjątkiem return false.
chwi

@chwi Cóż, biorąc dosłownie „nie liczbę”, masz rację, ale nie o to tutaj chodzi. W rzeczywistości szukam dokładnie tego, co to jest semantyka NaN(jak w pythonie, co można uzyskać float('inf') * 0), a zatem chociaż ciąg „Hello” nie jest liczbą, ale nie jest tak, NaNponieważ NaNwciąż jest wartością liczbową!
Mahdi

@chwi: Masz rację, jeśli obsługa wyjątków dotyczy konkretnego wyjątku. Ale w tej odpowiedzi obsłużono wyjątek ogólny. Więc nie trzeba sprawdzać int(value)Dla wszystkich wyjątków Falsezostaną zapisane.
Harsha Biyani

3

Wszystkie metody określania, czy zmienna ma wartość NaN czy None:

Brak typu

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

Typ 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

Jak usunąć elementy NaN (float) z listy mieszanych typów danych

Jeśli masz iterowalne typy mieszane, oto rozwiązanie, które nie używa 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]

Ocena zwarcia oznacza, że isnannie będą wywoływane wartości, które nie są typu „zmiennoprzecinkowego”, jak False and (…)szybko ocenia, Falsebez konieczności oceny prawej strony.


1

W Pythonie 3.6 sprawdzenie wartości ciągu x math.isnan (x) i np.isnan (x) powoduje błąd. Nie mogę więc sprawdzić, czy podana wartość to NaN, czy nie, jeśli wcześniej nie wiem, że jest to liczba. Poniższe wydają się rozwiązać ten problem

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

1

Wygląda na to, że sprawdzenie, czy jest równe sobie

x!=x

jest najszybszy.

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

Dla pływaka typu 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

dla ciągów w pandzie weź pd.isnull:

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

funkcja jako ekstrakcja funkcji dla 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

Po co ta obniżka?
Max Kleiner

isnull zwraca true dla nie tylko wartości NaN.
Boris
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.