webentwicklung-frage-antwort-db.com.de

NumPy oder Pandas: Bewahrt den Array-Typ als Ganzzahl, während er einen NaN-Wert hat

Gibt es eine bevorzugte Möglichkeit, den Datentyp eines numpy-Arrays als int (oder int64 oder was auch immer) festzuhalten, während ein Element dennoch als numpy.NaN aufgeführt ist?

Insbesondere konvertiere ich eine interne Datenstruktur in einen Pandas DataFrame. In unserer Struktur haben wir ganzzahlige Spalten, die noch über NaNs verfügen (der dtype der Spalte ist jedoch int). Es scheint alles als Float umzuwandeln, wenn wir dies zu einem DataFrame machen, aber wir möchten wirklich int sein.

Gedanken?

Dinge versucht:

Ich habe versucht, die Funktion from_records() unter pandas.DataFrame mit coerce_float=False zu verwenden, und dies hat nicht geholfen. Ich habe auch versucht, NumPy-maskierte Arrays zu verwenden, mit NaN fill_value, was auch nicht funktioniert hat. Bei all diesen wurde der Spaltendatentyp zu einem Float.

108
ely

Diese Funktion wurde zu Pandas hinzugefügt (beginnend mit Version 0.24): https://pandas.pydata.org/pandas-docs/version/0.24/whatsnew/v0.24.0.html#optional-integer-na -Unterstützung

An dieser Stelle ist die Verwendung der Erweiterung dtype Int64 (großgeschrieben) anstelle des Standardtyps d64 int64 (Kleinbuchstaben) erforderlich.

20
techvslife

NaN kann nicht in einem Integer-Array gespeichert werden. Dies ist im Moment eine bekannte Einschränkung von Pandas; Ich habe darauf gewartet, dass mit den NA-Werten in NumPy Fortschritte erzielt werden können (ähnlich den NAs in R), aber es wird mindestens 6 Monate bis zu einem Jahr dauern, bevor NumPy diese Funktionen erhält, wie es scheint:

http://pandas.pydata.org/pandas-docs/stable/gotchas.html#support-for-integer-na

(Diese Funktion wurde hinzugefügt, beginnend mit Version 0.24 von Pandas. Beachten Sie jedoch, dass die Erweiterung dtype Int64 (großgeschrieben) anstelle des Standardtyps d64 int64 (Kleinschreibung) erforderlich ist: https: // pandas.pydata.org/pandas-docs/version/0.24/whatsnew/v0.24.0.html#optional-integer-na-support )

92
Wes McKinney

Wenn die Leistung nicht das Hauptproblem ist, können Sie stattdessen Zeichenfolgen speichern.

df.col = df.col.dropna().apply(lambda x: str(int(x)) )

Dann können Sie mit NaN so viel mischen, wie Sie möchten. Wenn Sie wirklich Ganzzahlen haben möchten, können Sie je nach Anwendung -1 oder 0 oder 1234567890 oder einen anderen dedizierten Wert verwenden, um NaN darzustellen. 

Sie können die Spalten auch temporär duplizieren: eine wie Sie haben, mit Floats; der andere experimentell, mit Ints oder Streichern. Fügt dann an jeder sinnvollen Stelle asserts ein und prüft, ob die beiden synchron sind. Nach ausreichender Prüfung können Sie die Schwimmer loslassen. 

7
osa

Dies ist keine Lösung für alle Fälle, aber meine (genomische Koordinaten) habe ich verwendet, um 0 als NaN zu verwenden

a3['MapInfo'] = a3['MapInfo'].fillna(0).astype(int)

Dies ermöglicht zumindest die Verwendung des richtigen 'nativen' Spaltentyps, Operationen wie Subtraktion, Vergleich usw. funktionieren erwartungsgemäß

3
pufferfish

Pandas v0.24 +

Die Funktionalität zur Unterstützung von NaN in Ganzzahlreihen ist ab Version 0.24 verfügbar. Es gibt Informationen daz im Abschnitt "Was ist neu" in Version 0.24 und weitere Details unter Nullable Integer Data Type .

Pandas v0.23 und früher

Im Allgemeinen ist es am besten, mit float Serien zu arbeiten, wenn dies möglich ist, auch wenn die Serien aufgrund der Einbeziehung von int Werten von float auf NaN hochgestuft werden. Dies ermöglicht vektorisierte NumPy-basierte Berechnungen, bei denen andernfalls Schleifen auf Python-Ebene verarbeitet würden.

Die Dokumente tun vorschlagen : "Eine Möglichkeit ist, dtype=object Arrays statt. "Zum Beispiel:

s = pd.Series([1, 2, 3, np.nan])

print(s.astype(object))

0      1
1      2
2      3
3    NaN
dtype: object

Aus kosmetischen Gründen, z.B. Ausgabe in eine Datei, kann dies vorzuziehen sein.

Pandas v0.23 und früher: Hintergrund

NaN gilt als float . Das docs currently (from v0.23) gibt den Grund an, warum Ganzzahlreihen auf float hochgestuft werden:

Da NumPy keine leistungsstarke NA-Unterstützung von Grund auf bietet, besteht das Hauptproblem in der Fähigkeit, NAs in ganzzahligen Arrays darzustellen.

Dieser Kompromiss wird größtenteils aus Speicher- und Leistungsgründen getroffen, und auch damit die resultierende Serie weiterhin "numerisch" ist.

Die Dokumente enthalten auch Regeln angeben für das Upcasting aufgrund der NaN -Einbeziehung:

Typeclass   Promotion dtype for storing NAs
floating    no change
object      no change
integer     cast to float64
boolean     cast to object
2
jpp

Ich wollte nur hinzufügen, dass für den Fall, dass Sie versuchen, einen float (1.143) -Vektor in eine Ganzzahl (1) zu konvertieren, bei der NA in den neuen 'Int64'-D-Typ konvertiert wird, Sie eine Fehlermeldung erhalten. Um dies zu lösen, müssen Sie die Zahlen runden und dann ".astype ('Int64')" eingeben.

s1 = pd.Series([1.434, 2.343, np.nan])
#without round() the next line returns an error 
s1.astype('Int64')
#cannot safely cast non-equivalent float64 to int64
##with round() it works
s1.round().astype('Int64')
0      1
1      2
2    NaN
dtype: Int64

Mein Anwendungsfall ist, dass ich eine Float-Reihe habe, die ich auf int runden möchte, aber wenn Sie .round () tun, bleibt ein '* .0' am Ende der Zahl, sodass Sie diese 0 vom Ende bis zum löschen können Umwandlung in int.

Dies ist jetzt möglich, da Pandas v 0.24.0

pandas 0.24.x - Versionshinweise Zitat: "Pandas hat die Fähigkeit erworben, ganzzahlige Datentypen mit fehlenden Werten zu halten.

0
mork