Warum kann itertools.groupby die NaNs in Listen gruppieren, aber nicht in numpy Arrays

MSeifert:

Es fällt mir schwer, ein Problem zu debuggen, bei dem der Float nanin a listund nanin a numpy.arrayunterschiedlich behandelt wird, wenn diese verwendet werden in itertools.groupby:

Angesichts der folgenden Liste und Array:

from itertools import groupby
import numpy as np

lst = [np.nan, np.nan, np.nan, 0.16, 1, 0.16, 0.9999, 0.0001, 0.16, 0.101, np.nan, 0.16]
arr = np.array(lst)

Wenn ich die Liste durchlaufe, werden die zusammenhängenden nans gruppiert:

>>> for key, group in groupby(lst):
...     if np.isnan(key):
...         print(key, list(group), type(key))
nan [nan, nan, nan] <class 'float'>
nan [nan] <class 'float'>

Wenn ich das Array jedoch verwende, werden aufeinanderfolgende nans in verschiedene Gruppen eingeteilt:

>>> for key, group in groupby(arr):
...     if np.isnan(key):
...         print(key, list(group), type(key))
nan [nan] <class 'numpy.float64'>
nan [nan] <class 'numpy.float64'>
nan [nan] <class 'numpy.float64'>
nan [nan] <class 'numpy.float64'>

Auch wenn ich das Array wieder in eine Liste konvertiere:

>>> for key, group in groupby(arr.tolist()):
...     if np.isnan(key):
...         print(key, list(group), type(key))
nan [nan] <class 'float'>
nan [nan] <class 'float'>
nan [nan] <class 'float'>
nan [nan] <class 'float'>

Ich benutze:

numpy 1.11.3
python 3.5

Ich weiß das im Allgemeinen. nan != nanWarum führen diese Operationen zu unterschiedlichen Ergebnissen? Und wie ist es möglich, dass groupbyGruppen überhaupt gruppiert werden nankönnen?

Alex Riley:

Python-Listen sind nur Arrays von Zeigern auf Objekte im Speicher. Insbesondere lstenthält Zeiger auf das Objekt np.nan:

>>> [id(x) for x in lst]
[139832272211880, # nan
 139832272211880, # nan
 139832272211880, # nan
 139832133974296,
 139832270325408,
 139832133974296,
 139832133974464,
 139832133974320,
 139832133974296,
 139832133974440,
 139832272211880, # nan
 139832133974296]

( np.nanist bei 139832272211880 auf meinem Computer.)

Andererseits sind NumPy-Arrays nur zusammenhängende Speicherbereiche. Dies sind Bereiche von Bits und Bytes, die von NumPy als eine Folge von Werten (Floats, Ints usw.) interpretiert werden.

Das forProblem ist groupby, dass Python diese Bytes in ein geeignetes Python-Objekt packen muss , wenn Sie Python auffordern, über ein NumPy-Array mit schwebenden Werten (auf einer Schleife oder Ebene) zu iterieren . Es erstellt ein brandneues Python-Objekt im Speicher für jeden einzelnen Wert im Array, während es iteriert.

Sie können beispielsweise sehen, dass für jeden nanWert unterschiedliche Objekte erstellt werden, wenn .tolist()Folgendes aufgerufen wird:

>>> [id(x) for x in arr.tolist()]
[4355054616, # nan
 4355054640, # nan
 4355054664, # nan
 4355054688,
 4355054712,
 4355054736,
 4355054760,
 4355054784,
 4355054808,
 4355054832,
 4355054856, # nan
 4355054880]

itertools.groupbykann np.nanfür die Python-Liste gruppiert werden, da beim Vergleich von Python-Objekten zuerst die Identität überprüft wird . Da diese Zeiger auf nanalle auf dasselbe np.nanObjekt zeigen, ist eine Gruppierung möglich.

Die Iteration über das NumPy-Array ermöglicht jedoch nicht, dass diese anfängliche Identitätsprüfung erfolgreich ist. Daher greift Python auf die Überprüfung der Gleichheit zurück, nan != nanwie Sie sagen.

Dieser Artikel stammt aus dem Internet. Bitte geben Sie beim Nachdruck die Quelle an.

Bei Verstößen wenden Sie sich bitte [email protected] Löschen.

bearbeiten am
0

Lass mich ein paar Worte sagen

0Kommentare
LoginNach der Teilnahme an der Überprüfung

Verwandte Artikel

Warum haben Python-Listen pop (), aber nicht push ()

In Golang, warum kann eine Schnittstellenvariable die Adresse einer Strukturvariablen erhalten, aber nicht von einer Basistypvariablen?

Warum kann ich 1 als Short übergeben, aber nicht die int-Variable i?

Warum ist die Größe des Arrays als konstante Variable in C nicht zulässig, aber in C ++?

Warum kann ich nicht aus dieser Endlosschleife von itertools ausbrechen?

kann nan nicht in int umwandeln (aber es gibt keine nans)

Warum kann std :: apply ein Lambda aufrufen, aber nicht die entsprechende Vorlagenfunktion?

Warum funktioniert die Karte nicht, aber foreach?

Wie vergleiche ich numpy Arrays, die nans ignorieren?

Die einfache Mehrfachverarbeitungsfunktion funktioniert nicht, aber warum

Warum erlaubt numpy nicht die Zuweisung eines doppelt indizierten numpy-Arrays?

Variable mit globalem Gültigkeitsbereich, aber warum kann die Funktion nicht zugreifen?

Die lokale Konstantenvariable ist nicht auswertbar, kann aber nicht herausfinden, warum

Warum funktioniert "NOT IN" nicht, aber die Unterabfrage "NOT IN" funktioniert?

Warum kann ich einen Haken bedingt in die eine, aber nicht in die andere Richtung rufen?

Warum funktioniert die eingebaute Funktion abs () nicht mit Python-Listen, sondern korrekt mit NumPy-Arrays und Pandas-Serien (wie es vektorisiert wäre)?

Warum kann ich context.read nicht in build () verwenden, aber ich kann Provider.of mit listen: false verwenden?

Warum kann ich numpy in meinen Python-Interpreter importieren, aber RHEL sagt, dass numpy nicht installiert ist?

Magic Square in Python Fehler in Listen, aber nicht in Numpy Arrays

Die Python-Funktion bleibt hängen (kein Fehler), aber ich kann nicht verstehen, warum

Warum kann ich im Fall des zweidimensionalen Arrays von int ** in int * konvertieren, aber nicht im Fall des Arrays von Zeigern?

Cucumberjs and Gherkin: Warum kann ich die Schritte "Und" und "Aber" nicht verwenden?

Warum kann ich die Operatoren für - (Negation) und ! (nicht) aber nicht ~ (bitweise nicht)?

Python gruppieren nach drei Listen mit itertools

"lokale Variable 'resol', auf die vor der Zuweisung verwiesen wird", kann aber nicht verstehen, warum

Warum kann meine Seite die Datenattribute von Vue.js 2 erhalten, ist aber nicht reaktiv?

Warum Firebase authUI die Anmeldung bei Google jetzt nicht verwenden kann, sich aber vorher anmelden kann

warum numpy gemischte Datentypen zulässt, aber die Dokumentation sagt, dass dies nicht möglich ist?

Warum kann ich die Referenzvariable nicht erneut binden, aber das Referenzfeld in der Struktur?

TOP Liste

heißlabel

Archiv