Was ist NaN? NaN Zoya (Python) (394 Tage zu spät)

update1 2020-01-25: Tippfehlerbehebung IEEE745-> IEEE 754

In [1]: from datetime import datetime  
In [2]: (datetime(2020, 1, 11) - datetime(2018, 12, 13)).days                           
Out[2]: 394

Ich werde den Umgang mit Nan in Python erklären. Im Folgenden wird die Notation von nan als Konzept als NaN bezeichnet.

Disclaimer: Dieser Beitrag ist für justInCase Adventskalender 2018 und wurde nach einem Zeitraum von ca. 400 Tagen veröffentlicht, jedoch aufgrund der Laufzeit, des Inhalts Erfüllt nicht.

einpacken

Verifizierungsumgebung wird am Ende beschrieben

Umgang mit NaN in IEEE754

Weitere Informationen finden Sie im vorherigen Artikel Was ist NaN? NaN Zoya (R).

Beachten Sie, dass sich leises NaN in allgemeinen numerischen Operationen ausbreitet. Was sollten Ihrer Meinung nach die folgenden beiden Werte zurückgeben? Tatsächlich ändert sich die Behandlung von NaN bei min und max zwischen IEEE 754-2008 und IEEE 754-2019. Die Erklärung von ist in einem anderen Artikel.

min(1.0, float('nan'))
max(1.0, float('nan'))

So rufen Sie NaN in Python auf

Es gibt kein Sprachliteral. Wenn Sie "float (" nan ")" oder "numpy" aufrufen, für das kein Modulaufruf erforderlich ist, wird "np.nan" häufig verwendet.

import math
import decimal
import numpy as np
import pandas as pd

float('nan')
math.nan
0.0 * math.inf
math.inf / math.inf
# 0.0/0.0 ZeroDivisionError in Python. C, R,Viele Sprachen wie Julia geben NaN zurück
np.nan
np.core.numeric.NaN
pd.np.nan

Alle Float-Objekte. Die Objekte, auf die numpy`` pandas verweist, sind dieselben, obwohl sie keine Singleton-Objekte sind.

nans = [float('nan'), math.nan, 0 * math.inf, math.inf / math.inf, np.nan, np.core.numeric.NaN, pd.np.nan]

import pprint
pprint.pprint([(type(n), id(n)) for n in nans])
# [(<class 'float'>, 4544450768),
#  (<class 'float'>, 4321186672),
#  (<class 'float'>, 4544450704),
#  (<class 'float'>, 4544450832),
#  (<class 'float'>, 4320345936),
#  (<class 'float'>, 4320345936),
#  (<class 'float'>, 4320345936)]

float ('nan') selbst ist ein unveränderliches Objekt der float-Klasse, also hashbar. Es kann also ein Wörterbuchschlüssel sein, aber seltsamerweise können Sie mehrere Nans hinzufügen. Und wenn Sie den Schlüssel nicht im Voraus an eine Variable binden, können Sie ihn nicht erneut abrufen. Es wird angenommen, dass dies auf die Tatsache zurückzuführen ist, dass alle Ergebnisse des Vergleichsoperators von "NaN" "Falsch" sind, dh "float (" nan ") == float (" nan ")" -> "falsch".

>>> d = {float('nan'): 1, float('nan'): 2, float('nan'): 3}
>>> d
{nan: 1, nan: 2, nan: 3}
>>> d[float('nan')]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: nan

Beachten Sie die Existenz von Objekten mit NaN-ähnlichen Eigenschaften, die keine Float-Klassen sind. Insbesondere sind "pd.NaT" und "np.datetime64 (" NaT ")" verschiedene Klassen.

decimal.Decimal('nan')
pd.NaT
np.datetime64("NaT")

# >>> type(decimal.Decimal('nan'))
# <class 'decimal.Decimal'>

# >>> type(pd.NaT)
# <class 'pandas._libs.tslibs.nattype.NaTType'>

# >>> type(np.datetime64("NaT"))
# <class 'numpy.datetime64'>

Daher sind die folgenden Vorsichtsmaßnahmen erforderlich, wenn Sie "np.isnat" verwenden.

>>> np.isnat(pd.NaT)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: ufunc 'isnat' is only defined for datetime and timedelta.

>>> np.isnat(np.datetime64("NaT"))
True

NaN-Check

math.isnan
np.isnan
pd.isna

Die aktuelle Situation von math.isnan ist hier. https://github.com/python/cpython/blob/e42b705188271da108de42b55d9344642170aa2b/Include/pymath.h#L88-L103 https://github.com/python/cpython/blob/34fd4c20198dea6ab2fe8dc6d32d744d9bde868d/Lib/_pydecimal.py#L713-L726

/* Py_IS_NAN(X)
 * Return 1 if float or double arg is a NaN, else 0.
 * Caution:
 *     X is evaluated more than once.
 *     This may not work on all platforms.  Each platform has *some*
 *     way to spell this, though -- override in pyconfig.h if you have
 *     a platform where it doesn't work.
 * Note: PC/pyconfig.h defines Py_IS_NAN as _isnan
 */
#ifndef Py_IS_NAN
#if defined HAVE_DECL_ISNAN && HAVE_DECL_ISNAN == 1
#define Py_IS_NAN(X) isnan(X)
#else
#define Py_IS_NAN(X) ((X) != (X))
#endif
#endif
def _isnan(self):
    """Returns whether the number is not actually one.
    0 if a number
    1 if NaN
    2 if sNaN
    """
    if self._is_special:
        exp = self._exp
        if exp == 'n':
            return 1
        elif exp == 'N':
            return 2
    return 0

Beachten Sie, dass die Pandas-Methode "isna" (und "isnull") "True" als fehlenden Wert nicht nur für "float nan", sondern auch für "None" und "pd.NaT" zurückgibt. Wenn pandas.options.mode.use_inf_as_na = True, gibt es einen Tipp, dass np.inf auch als fehlender Wert beurteilt wird.

>>> pd.isna(math.nan)
True
>>> pd.isna(None)
True
>>> pd.isna(math.inf)
False
>>> pandas.options.mode.use_inf_as_na = True
>>> pd.isna(math.inf)
True

Über die Pandas-Methode

Die direkte Methode des Pandas-Objekts verwendet ein skalares oder Array-ähnliches Argument, und der Rückgabewert ist ein Bool mit der gleichen Größe wie das Argument. Andererseits ist die direkte Methode von pd.DataFrame ein DataFrame sowohl für das Argument als auch für den Rückgabewert.

pd.isna # for scalar or array-like
pd.DataFrame.isna # for DataFrame

Das Array-ähnliche Objekt bezieht sich speziell auf das folgende Objekt. (https://github.com/pandas-dev/pandas/blob/v0.25.3/pandas/core/dtypes/missing.py#L136-L147)

ABCSeries,
np.ndarray,
ABCIndexClass,
ABCExtensionArray,
ABCDatetimeArray,
ABCTimedeltaArray,

Es sollte beachtet werden, dass entweder für "pd.isna" oder "pd.isnull" genau das gleiche ist (eine unter dem Gesichtspunkt der Lesbarkeit einheitliche Verwendung ist wünschenswert).

# https://github.com/pandas-dev/pandas/blob/v0.25.3/pandas/core/dtypes/missing.py#L125
>>> id(pd.isnull)
4770964688
>>> id(pd.isna)
4770964688

ist Methodenzusammenfassung

Wenn Sie nicht auf einen unerwarteten Fehler stoßen möchten, ist "pd.isna" sicher, aber seien Sie vorsichtig, da es nach dem Urteil "Decimal (" nan ")" ausläuft.

math.nan decimal.Decimal('nan') np.datetime64("NaT") pd.NaT math.inf None
math.isnan True True error error False error
decimal.Decimal.is_nan error True error error error error
np.isnan True error True error False error
pd.isna True False True True False True
np.isnat error error True error error error

Andere

Überprüfen Sie den binären Ausdruck. Sie können sehen, dass es ruhig NaN ist.

>>> import struct
>>> xs = struct.pack('>d', math.nan)
>>> xs
b'\x7f\xf8\x00\x00\x00\x00\x00\x00'
>>> xn = struct.unpack('>Q', xs)[0]
>>> xn
9221120237041090560
>>> bin(xn)
'0b111111111111000000000000000000000000000000000000000000000000000'

Zusammenfassung (Repost)

--NaN in Python folgt NaN in IEEE754, aber hier und da gibt es einige süchtig machende Punkte. --Beachten Sie die Existenz von "Decimal (" nan ")", "pd.NaT", "numpy.datetime64 (" NaT ")", die nicht float nan sind.

Schließlich Wenn Sie diese Art von verrückter Geschichte lieben, besuchen Sie uns bitte bei justInCase. https://www.wantedly.com/companies/justincase

das ist alles

Überprüfungsumgebung

$ uname -a
Darwin MacBook-Pro-3.local 18.7.0 Darwin Kernel Version 18.7.0: Sat Oct 12 00:02:19 PDT 2019; root:xnu-4903.278.12~1/RELEASE_X86_64 x86_64

$ python
Python 3.7.4 (default, Nov 17 2019, 08:06:12) 
[Clang 10.0.1 (clang-1001.0.46.4)] on darwin

$ pip list | grep -e numpy -e pandas
numpy                    1.18.0     
pandas                   0.25.3   

Recommended Posts

Was ist NaN? NaN Zoya (Python) (394 Tage zu spät)
Was ist Python?
Was ist Python?
[Python] Was ist Pipeline ...
[Python] Was ist virtualenv?
[Python] Python und Sicherheit - is Was ist Python?
[Python] * args ** Was ist kwrgs?
Python-Grundkurs (1 Was ist Python?)
[Python] Was ist @? (Über Dekorateure)
[Python] Was ist der sortierte Schlüssel?
Python für Anweisung ~ Was ist iterierbar ~
Wofür ist der Python-Unterstrich (_)?
Python> Was ist ein erweitertes Slice?
[Python] Was ist Pandas Series und DataFrame?
[Python] Was wird durch Mehrfachvererbung geerbt?
Was für eine Programmiersprache ist Python?
Was ist "Mahjong" in der Python-Bibliothek? ??
Was ist ein Hund? Python-Installationsvolumen
Was ist ein Namespace?
Was ist ein Algorithmus? Einführung in den Suchalgorithmus] ~ Python ~
Was ist copy.copy ()
Was ist "funktionale Programmierung" und "objektorientiert"? Python Edition
Python ist einfach
Was ist Django? .. ..
Was ist dotenv?
Was ist POSIX?
Was ist im Docker Python-Image pfeifend?
Was ist Linux?
Was ist klass?
Ich habe Python ausprobiert! ] Heute Abschluss von "Jeder Python! Was ist Python!"!
Was ist SALOME?
Was ist Linux?
Was vergleichst du mit Python und ==?
Was ist Hyperopt?
Python ist eine Instanz
Was ist Linux?
[Einführung in die Udemy Python3 + -Anwendung] 54. Was ist Docstrings?
Was ist Pyvenv?
Was ist __call__?
Was ist Linux?
Sag mir, was eine gleichwinklige Abbildung ist, Python!
Was ist der [Ruby / Python / Java / Swift / JS] -Algorithmus?
[Python] Kalender Heatmap [Plotly] Memo
Was ist Gott? Erstelle einen einfachen Chatbot mit Python
Python Int ist unendlich
Was ist eine Distribution?
Was ist Piotroskis F-Score?
Was ist Raspberry Pi?
Was ist das Calmar-Verhältnis?
Was ist ein Terminal?
[PyTorch Tutorial ①] Was ist PyTorch?
Was ist Hyperparameter-Tuning?
Was ist ein Hacker?
Was ist JSON? .. [Hinweis]
Wofür ist Linux?
Was ist ein Zeiger?