Wie kann ich nach NaN-Werten suchen?

981

float('nan')ergibt Nan (keine Zahl). Aber wie überprüfe ich das? Sollte sehr einfach sein, aber ich kann es nicht finden.

Jack Ha
quelle
20
Informationen zur
Craig McQueen

Antworten:

1280

math.isnan (x)

Geben Sie zurück, Truewenn x ein NaN (keine Zahl) ist, und Falseansonsten.

>>> import math
>>> x = float('nan')
>>> math.isnan(x)
True
gimel
quelle
5
@ charlie-parker: In Python3 ist math.isnan immer noch Teil des Mathematikmoduls. docs.python.org/3/library/math.html#math.isnan . Verwenden Sie numpy.isnan, wenn Sie möchten. Diese Antwort ist nur ein Vorschlag.
Gimel
2
@ SittingBull Siehe docs.python.org/3/library/functions.html#float "Wenn das Argument eine Zeichenfolge ist, sollte es eine Dezimalzahl enthalten" oder "Infinity" "inf" "nan"
gimel
35
ist math.isnanbevorzugt zu np.isnan()?
TMWP
34
@ TMWP möglicherweise ... import numpybenötigt etwa 15 MB RAM, während import mathetwa 0,2 MB
petrpulc
9
@TMWP: Wenn Sie NumPy verwenden, numpy.isnanist dies eine überlegene Wahl, da es NumPy-Arrays verarbeitet. Wenn Sie nicht NumPy verwenden, gibt es keinen Vorteil eine NumPy Abhängigkeit zu nehmen und verbringen die Zeit NumPy nur für eine NaN Scheck zu laden (aber wenn Sie die Art von Code schreiben , die NaN Kontrollen der Fall ist, ist es wahrscheinlich , dass Sie sollten verwenden NumPy).
user2357112 unterstützt Monica
359

Der übliche Weg, um auf ein NaN zu testen, besteht darin, festzustellen, ob es sich selbst entspricht:

def isNaN(num):
    return num != num
Chris Jester-Young
quelle
8
Ein Wort der Warnung: Bärs Kommentar unten zitieren "Für Leute, die mit Python <= 2,5 stecken. Nan! = Nan hat nicht zuverlässig funktioniert. Stattdessen wurde numpy verwendet." Trotzdem habe ich noch nie gesehen, dass es fehlschlägt.
Mai
22
Ich bin mir sicher, dass es angesichts der Überlastung des Bedieners viele Möglichkeiten gibt, diese Funktion zu verwechseln. gehen Sie mit math.isnan ()
djsadinoff
4
In der oben erwähnten 754-Spezifikation heißt es, dass NaN == NaN immer falsch sein sollte, obwohl es nicht immer als solches implementiert ist. Ist es nicht möglich, dass Mathe und / oder Numpy dies sowieso unter der Haube überprüfen?
Hari Ganesan
Vielen Dank . Dies ist auch 15-20x schneller als die Verwendung von np.isnan, wenn eine Operation an einem Skalar ausgeführt wird
thomas.mac
5
Obwohl dies funktioniert und bis zu einem gewissen Grad Sinn macht, bin ich ein Mensch mit Prinzipien und erkläre dies hiermit als verbotene Hexerei. Bitte verwenden Sie stattdessen math.isnan.
Gonzalo
152

numpy.isnan(number)sagt dir, ob es ist NaNoder nicht.

mavnn
quelle
3
Funktioniert auch in Python Version 2.7.
Michel Keijzers
6
numpy.all(numpy.isnan(data_list))ist auch nützlich, wenn Sie feststellen müssen, ob alle Elemente in der Liste nan sind
Jay P.
3
Keine Notwendigkeit für NumPy:all(map(math.isnan, [float("nan")]*5))
Sleblanc
6
Als diese Antwort vor 6 Jahren geschrieben wurde, war Python 2.5 noch gebräuchlich - und math.isnan war nicht Teil der Standardbibliothek. Heute hoffe ich wirklich, dass dies vielerorts nicht der Fall ist!
Mavnn
4
Beachten Sie, dass np.isnan () nicht den Typ decimal.Decimal verarbeitet (ebenso viele Funktionen von numpy). math.isnan () behandelt.
Comte
55

Hier sind drei Möglichkeiten, wie Sie testen können, ob eine Variable "NaN" ist oder nicht.

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

Ausgabe

It's pd.isna  : True
It's np.isnan  : True
It's math.isnan  : True
M. Hamza Rajput
quelle
2
pd.isna (Wert) hat viele Probleme gespart! Arbeiten wie ein Zauber!
Abhishake
1
ps.isna()löst meine Probleme. Vielen Dank!
Darthbhyrava
32

Hier ist eine Antwort, mit der gearbeitet wird:

  • NaN-Implementierungen gemäß IEEE 754-Standard
    • dh: Pythons NaN : float('nan'), numpy.nan...
  • Alle anderen Objekte: Zeichenfolge oder was auch immer (löst keine Ausnahmen aus, wenn sie auftreten)

Ein nach dem Standard implementiertes NaN ist der einzige Wert, für den der Ungleichheitsvergleich mit sich selbst True zurückgeben sollte:

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

Und einige Beispiele:

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

Ausgabe:

nan      : True
nan      : True
55       : False
'string' : False
<function <lambda> at 0x000000000927BF28> : False
x0s
quelle
1
Die Serie, die ich überprüfe, ist, dass Zeichenfolgen mit fehlenden Werten 'nans' (???) sind, sodass diese Lösung dort funktioniert, wo andere fehlgeschlagen sind.
Keithpjolley
numpy.nanist ein reguläres Python- floatObjekt, genau wie die von float('nan'). Die meisten NaNs, denen Sie in NumPy begegnen, sind nicht das numpy.nanObjekt.
user2357112 unterstützt Monica
numpy.nandefiniert seinen NaN Wert auf seinem eigenen in der zugrunde liegenden Bibliothek in C . Pythons NaN wird nicht verpackt. Jetzt entsprechen beide dem IEEE 754-Standard, da sie auf der C99-API basieren.
x0s
@ user2357112supportsMonica: Python und numpy NaN verhalten sich tatsächlich nicht gleich: float('nan') is float('nan')(nicht eindeutig) und np.nan is np.nan(eindeutig)
x0s
@ x0s: Das hat nichts mit NumPy zu tun. np.nanist ein bestimmtes Objekt, während jeder float('nan')Aufruf ein neues Objekt erzeugt. Wenn du das getan nan = float('nan')hättest, würdest du es auch bekommen nan is nan. Wenn Sie einen konstruierten tatsächlichen NumPy NaN mit so etwas wie np.float64('nan'), dann würden Sie bekommen np.float64('nan') is not np.float64('nan')auch .
user2357112 unterstützt Monica
28

Ich bin eigentlich nur darauf gestoßen, aber für mich war es die Suche nach nan, -inf oder inf. Ich habe es gerade benutzt

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

Dies gilt für Zahlen, falsch für nan und beide inf und löst eine Ausnahme für Dinge wie Strings oder andere Typen aus (was wahrscheinlich eine gute Sache ist). Außerdem müssen keine Bibliotheken wie math oder numpy importiert werden (numpy ist so verdammt groß, dass sich die Größe einer kompilierten Anwendung verdoppelt).

DaveTheScientist
quelle
9
math.isfinitewurde erst mit Python 3.2 eingeführt. Angesichts der Antwort von @DaveTheScientist aus dem Jahr 2012 war es nicht gerade "das Rad neu erfinden" - die Lösung steht immer noch für diejenigen, die mit Python 2 arbeiten.
sudo_coffee
22

math.isnan ()

oder vergleichen Sie die Nummer mit sich selbst. NaN ist immer! = NaN, andernfalls (z. B. wenn es sich um eine Zahl handelt) sollte der Vergleich erfolgreich sein.

Tomalak
quelle
6
Für Leute, die mit Python <= 2,5 stecken. Nan! = Nan hat nicht zuverlässig gearbeitet. Stattdessen numpy verwendet.
Bär
16

Eine andere Methode, wenn Sie auf <2.6 stecken, Sie haben keine Numpy und Sie haben keine IEEE 754-Unterstützung:

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

Nun, ich habe diesen Beitrag eingegeben, weil ich einige Probleme mit der Funktion hatte:

math.isnan()

Beim Ausführen dieses Codes tritt ein Problem auf:

a = "hello"
math.isnan(a)

Es wird eine Ausnahme ausgelöst. Meine Lösung dafür ist eine weitere Überprüfung:

def is_nan(x):
    return isinstance(x, float) and math.isnan(x)
Idok
quelle
3
Es wurde wahrscheinlich herabgestimmt, weil isnan () einen Float nimmt, keinen String. An der Funktion ist nichts auszusetzen, und die Probleme liegen nur in seinem versuchten Gebrauch. (Für diesen speziellen Anwendungsfall ist seine Lösung gültig, aber es ist keine Antwort auf diese Frage.)
Peter Hansen
6
Seien Sie vorsichtig, wenn Sie auf diese Weise nach Typen suchen. Dies funktioniert zB bei numpy.float32 NaNs nicht. Besser einen Versuch / außer Konstruktion verwenden: def is_nan(x): try: return math.isnan(x) except: return False
Rob
3
NaN bedeutet nicht , dass ein Wert keine gültige Zahl ist. Es ist Teil der IEEE-Gleitkommadarstellung, anzugeben, dass ein bestimmtes Ergebnis undefiniert ist. zB 0 / 0. Daher ist es bedeutungslos zu fragen, ob "Hallo" nan ist.
Brice M. Dempsey
2
Dies ist besser, weil NaN in jeder Liste von Strings, Ints oder Floats landen kann, also nützliche Überprüfung
RAFIQ
Ich musste genau dies implementieren, um String-Spalten in Pandas zu behandeln.
Cristian Garcia vor
7

Mit Python <2.6 endete ich mit

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

Dies funktioniert für mich mit Python 2.5.1 auf einer Solaris 5.9-Box und mit Python 2.6.5 unter Ubuntu 10

Mauro Bianchi
quelle
6
Dies ist nicht zu portabel, wie Windows dies manchmal nennt-1.#IND
Mike T
5

Ich empfange die Daten von einem Webdienst, der NaNals Zeichenfolge sendet 'Nan'. Aber es könnte auch andere Arten von Zeichenfolgen in meinen Daten geben, so dass eine einfache float(value)eine Ausnahme auslösen könnte. Ich habe die folgende Variante der akzeptierten Antwort verwendet:

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

Anforderung:

isnan('hello') == False
isnan('NaN') == True
isnan(100) == False
isnan(float('nan')) = True
Mahdi
quelle
1
odertry: int(value)
Chwi
@chwi also, was sagt dein Vorschlag über das valueSein NaNoder Nicht- Sein aus ?
Mahdi
Nun, da "keine Zahl" ist, ist alles, was nicht in ein int umgewandelt werden kann, tatsächlich keine Zahl, und die try-Anweisung wird fehlschlagen? Versuchen Sie, true zurückzugeben, außer false.
Chwi
@chwi Nun, wenn Sie "keine Zahl" wörtlich nehmen, haben Sie Recht, aber das ist hier nicht der Punkt. Tatsächlich suche ich genau nach der Semantik von NaN(wie in Python, woraus man kommen könnte float('inf') * 0), und daher ist die Zeichenfolge 'Hallo' zwar keine Zahl, aber auch nicht, NaNweil sie NaNimmer noch ein numerischer Wert ist!
Mahdi
@chwi: Sie sind korrekt, wenn die Ausnahmebehandlung für eine bestimmte Ausnahme gilt. In dieser Antwort wurden jedoch allgemeine Ausnahmen behandelt. Also keine Notwendigkeit zu prüfen int(value)Für alle Ausnahmen Falsewird geschrieben.
Harsha Biyani
3

Alle Methoden, um festzustellen, ob die Variable NaN oder None ist:

Kein Typ

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

NaN-Typ

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

So entfernen Sie NaN (float) -Elemente aus einer Liste gemischter Datentypen

Wenn Sie gemischte Typen in einer Iterable haben, ist hier eine Lösung, die numpy nicht verwendet:

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]

Kurzschlussauswertung bedeutet, dass isnanWerte, die nicht vom Typ 'float' sind, nicht aufgerufen werden, da sie False and (…)schnell ausgewertet werden, Falseohne dass die rechte Seite ausgewertet werden muss.

Sleblanc
quelle
1

In Python 3.6 löst das Überprüfen eines Zeichenfolgenwerts x math.isnan (x) und np.isnan (x) einen Fehler aus. Ich kann also nicht überprüfen, ob der angegebene Wert NaN ist oder nicht, wenn ich vorher nicht weiß, dass es sich um eine Zahl handelt. Das Folgende scheint dieses Problem zu lösen

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

Es scheint, dass zu überprüfen, ob es sich selbst gleich ist

x!=x

ist der schnellste.

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

Für nan vom Typ float

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

für Strings in Panda nimm pd.isnull:

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

die Funktion als Merkmalsextraktion für 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
quelle
Was für diese Reduzierung?
Max Kleiner
isnull gibt nicht nur für NaN-Werte true zurück.
Boris