Was ist der Unterschied zwischen NaN und None?


94

Ich lese zwei Spalten einer CSV-Datei mit Pandas readcsv()und weise die Werte dann einem Wörterbuch zu. Die Spalten enthalten Zeichenfolgen aus Zahlen und Buchstaben. Gelegentlich gibt es Fälle, in denen eine Zelle leer ist. Meiner Meinung nach sollte der Wert, der zu diesem Wörterbucheintrag gelesen wird, Noneaber stattdessen nanzugewiesen werden. Sicherlich Noneist eine leere Zelle aussagekräftiger, da sie einen Nullwert hat, während nannur gesagt wird, dass der gelesene Wert keine Zahl ist.

Ist mein Verständnis richtig, was ist der Unterschied zwischen Noneund nan? Warum wird statt nanzugewiesen None?

Außerdem hat meine Wörterbuchprüfung für leere Zellen Folgendes verwendet numpy.isnan():

for k, v in my_dict.iteritems():
    if np.isnan(v):

Dies gibt mir jedoch einen Fehler, der besagt, dass ich diese Prüfung nicht verwenden kann v. Ich denke, das liegt daran, dass eine Ganzzahl- oder Float-Variable und keine Zeichenfolge verwendet werden soll. Wenn dies zutrifft, wie kann ich vnach einer "leeren Zelle" / einem "leeren nanFall " suchen?


Der Text qwertyist keine Zahl.
Robert Harvey

1
@ RobertHarvey Ich weiß, also Nonewäre sicherlich eine bessere Beschreibung des Wertes einer leeren Zelle.
user1083734

Antworten:


105

NaN wird als Platzhalter verwendet für fehlende Daten konsistent in Pandas , ist die Konsistenz gut. Normalerweise lese / übersetze ich NaN als "vermisst" . Siehe auch den Abschnitt "Arbeiten mit fehlenden Daten" in den Dokumenten.

Wes schreibt in den Dokumenten 'Wahl der NA-Darstellung' :

Nach Jahren der Produktion hat sich [NaN] zumindest meiner Meinung nach angesichts der Situation in NumPy und Python im Allgemeinen als die beste Entscheidung erwiesen. Der besondere Wert NaN (Not-a-Number) verwendet wird überall als der NA - Wert, und es gibt API - Funktionen isnullund notnulldie sich über die dtypes verwendet werden kann , um NA - Werte zu erfassen.
...
Daher habe ich den pythonischen Ansatz „Praktikabilität schlägt Reinheit“ gewählt und die Fähigkeit zur Ganzzahl-NA gehandelt, um einen viel einfacheren Ansatz zu verwenden, bei dem ein spezieller Wert in Float- und Objekt-Arrays zur Bezeichnung von NA verwendet wird und Ganzzahl-Arrays zum Floating befördert werden, wenn NAs erforderlich sind eingeführt.

Hinweis: Die "gotcha", die Ganzzahlserien mit fehlenden Daten enthalten, werden in Floats übertragen .

Meiner Meinung nach ist der Hauptgrund für die Verwendung von NaN (über None), dass es mit dem Float64-D-Typ von numpy und nicht mit dem weniger effizienten Objekt-D- Typ gespeichert werden kann ( siehe NA-Typ-Promotions) .

#  without forcing dtype it changes None to NaN!
s_bad = pd.Series([1, None], dtype=object)
s_good = pd.Series([1, np.nan])

In [13]: s_bad.dtype
Out[13]: dtype('O')

In [14]: s_good.dtype
Out[14]: dtype('float64')

Jeff kommentiert (unten) dies:

np.nanermöglicht vektorisierte Operationen; Es ist ein Float-Wert, während Noneper Definition der Objekttyp erzwungen wird, wodurch im Grunde alle Effizienz in Numpy deaktiviert wird.

Also dreimal schnell wiederholen: Objekt == schlecht, Float == gut

Wenn man so sagt, funktionieren viele Operationen möglicherweise immer noch genauso gut mit None vs NaN (werden aber möglicherweise nicht unterstützt, dh sie liefern manchmal überraschende Ergebnisse ):

In [15]: s_bad.sum()
Out[15]: 1

In [16]: s_good.sum()
Out[16]: 1.0

Um die zweite Frage zu beantworten:
Sie sollten fehlende Daten (NaN) verwenden pd.isnullund pd.notnullauf diese testen.


18
nur 2c hier hinzufügen .... np.nanermöglicht vektorisierte Operationen; Es ist ein Float-Wert, während er Noneper Definition den objectTyp erzwingt und im Grunde alle Effizienz in Numpy deaktiviert. Wiederholen Sie ihn also dreimal schnell:object==bad, float==good
Jeff

Ist <NA>auch ein np.nan?
Gathide

18

NaNkann als numerischer Wert für mathematische Operationen verwendet werden, Nonekann (oder sollte zumindest nicht).

NaNist ein numerischer Wert, wie er im Gleitkomma-Standard IEEE 754 definiert ist . Noneist ein interner Python-Typ ( NoneType) und wäre in diesem Zusammenhang eher "nicht vorhanden" oder "leer" als "numerisch ungültig".

Das Hauptsymptom dafür ist, dass Sie NaN erhalten, wenn Sie beispielsweise einen Durchschnitt oder eine Summe für ein Array ausführen, das NaN enthält, sogar ein einzelnes ...

Andererseits können Sie keine mathematischen Operationen ausführen, die Noneals Operanden verwendet werden.

Je nach Fall können Sie NoneIhrem Algorithmus also mitteilen, dass bei Berechnungen keine ungültigen oder nicht vorhandenen Werte berücksichtigt werden sollen. Das würde bedeuten, dass der Algorithmus jeden Wert testen sollte, um festzustellen, ob dies der Fall ist None.

Numpy hat einige Funktionen NaN - Werte zu vermeiden , dass Ihre Ergebnisse, wie zu verunreinigen nansumund nan_to_numzum Beispiel.


Ich stimme Ihnen zu, dass None für nicht vorhandene Einträge verwendet werden sollte. Warum gibt df=pd.readcsv('file.csv')es mir NaNWerte für die leeren Zellen und nicht None? Soweit mir bekannt ist, sind pd.DataFrames nicht ausschließlich für Zahlen.
user1083734

Nun, es ist wahrscheinlich eine Design-Wahl. Ich nehme an, DataFrames und Series haben eine dtype, daher müssen ungültige Werte von dtype=floatdurch numerische Werte dargestellt werden, die NaNist und Nonenicht ist ( Noneist von NoneType).
Heltonbiker

Außerdem haben viele Pandas-Methoden ein naArgument, mit dem Sie entscheiden können, welchen Wert Sie verwenden
möchten

OK danke. Ich lese also keine Zahlen in meinen DataFrame, sondern Zeichenfolgen aus Zahlen und Buchstaben. Welche Art von Prüfung sollte ich verwenden, um leere Zellen zu erkennen? Ein Scheck wie; wenn dtype == float: ??
user1083734

Vielleicht hilft es, ein Beispiel Ihrer CSV-Daten zu veröffentlichen. Ich kann mir vorstellen, dass dtype, wenn es Zeichenfolgen gibt, Zeichenfolge für die gesamte Spalte (Serie) ist. Aber wenn nicht jede Zeile die gleiche Anzahl von Spalten hat, erhalten Sie möglicherweise nicht verfügbare Daten. Ich denke, das musst du überprüfen.
Heltonbiker

3

Die Funktion isnan()prüft, ob etwas "Keine Zahl" ist, und gibt zurück, ob eine Variable eine Zahl ist oder nicht, z. B. isnan(2)würde false zurückgegeben

Die Bedingung gibt myVar is not Nonezurück, ob die Variable definiert ist oder nicht

Ihr numpy-Array wird verwendet, isnan()da es ein Array von Zahlen sein soll und alle Elemente des Arrays mit NaNdiesen Elementen initialisiert werden. Diese Elemente werden als "leer" betrachtet.


1
Ich denke isnan(2)würde zurückkehren False, da 2 kein NaN ist.
Heltonbiker

Auch numpy.emptywird nicht initialisiert Array - Werte zu NaN. Die Werte werden einfach überhaupt nicht initialisiert.
Heltonbiker

5
Die richtige Überprüfung auf None-ness ist myVar is not Nonenicht myVar != None.
Jaime

3
Beachten Sie, dass dies np.isnan()nicht für Zeichenfolgenvariablen implementiert ist. Wenn Sie also eine Zeichenfolge übergeben, stürzt diese ab. Besser zu verwenden, pd.isnullwas mit Strings funktioniert.
Michael

-1

Nachfolgend sind die Unterschiede aufgeführt:

  • nan gehört zur Klasse float
  • None gehört zur Klasse NoneType

Ich fand den folgenden Artikel sehr hilfreich: https://medium.com/analytics-vidhya/dealing-with-missing-values-nan-and-none-in-python-6fc9b8fb4f31


Während dieser Link die Frage beantworten kann, ist es besser, die wesentlichen Teile der Antwort hier aufzunehmen und den Link als Referenz bereitzustellen. Nur-Link-Antworten können ungültig werden, wenn sich die verknüpfte Seite ändert. - Aus dem Rückblick
A. Kootstra

@ A.Kootstra Ich verstehe
eswara amirthan s

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.