Python-Bibliothek pandas 2.0 optimiert die Speicherverwaltung
Die neue Version der meistgenutzten Python-Library fĂĽr die Datenverarbeitung arbeitet mit Apache Arrow zusammen und fĂĽhrt Copy-on-Write ein.
(Bild: foxaon1987/Shutterstock.com)
- Patrick Höfler
Gut drei Jahre nach der ersten Hauptversion ist nun Version 2.0 von pandas erschienen. Das Release stabilisiert Funktionen, die teilweise bereits in pandas 1.5 enthalten waren, darunter die Extension Arrays, die Anbindung an Apache Arrow und Copy-on-Write.
Im Zuge des Versionssprungs hat das Team die Python-Bibliothek für die Verarbeitung und Analyse von Daten aufgeräumt und alle als überholt (deprecated) markierten Komponenten entfernt oder angepasst.
Videos by heise
Eigene Datentypen fĂĽr die Library
Bereits pandas 1.0 hat Extension Arrays (EAs) eingefĂĽhrt, die es erlauben, eigene Datentypen zu definieren, die von NumPy-Datentypen abweichen. Das Team hat innerhalb von pandas EAs implementiert, die fehlende Werte in beliebigen Datentypen wie Integer oder Boolean erlauben.
Da frühere Versionen an vielen Stellen implizit NumPy-Datentypen voraussetzen, funktionierte die EA-Anbindung nicht vollständig. Das pandas-Team hat sie über die 1.x-Serie sukzessive verbessert. In pandas 2.0 berücksichtigen die meisten Aufrufe die EA-eigenen Methoden, statt auf NumPy-Funktionen zurückzufallen. Das verbessert auch die Performance:
# pandas 1.5.3:
In[3]: ser = pd.Series(list(range(1, 1_000_000))
+ [pd.NA], dtype="Int64")
In[4]: %timeit ser.drop_duplicates()
22.7 ms ± 272 µs per loop \
(mean ± std. dev. of 7 runs, 10 loops each)
# pandas 2.0:
In[3]: ser = pd.Series(list(range(1, 1_000_000))
+ [pd.NA], dtype="Int64")
In[4]: %timeit ser.drop_duplicates()
7.54 ms ± 24 µs per loop \
(mean ± std. dev. of 7 runs, 100 loops each)
Unter anderem findet innerhalb von GroupBy-Operationen keine Umwandlung zu float mehr statt, sondern es gelten die EA-Konventionen. Neben der verbesserten Performance verhindert dieses Vorgehen Genauigkeitsverluste bei größeren Zahlen.
pandas 2.0 kennt fĂĽr fast alle I/O-Funktionen einen neuen Parameter, um automatisch zu EA-Datentypen umzuwandeln. Wenn der Parameter dtype_backend auf "numpy_nullable" gesetzt ist, gibt die Funktion ein DataFrame zurĂĽck, der nur aus Nullable-Datentypen besteht.
Außerdem lässt sich ein Index erzeugen, der Extension Arrays enthält. Das Vorgehen hat pandas 1.4.0 erstmals eingeführt, und mittlerweile sind alle Operationen effizient implementiert:
- Index-Operationen benutzen EA-Funktionen.
- Es gibt eine effiziente Engine, die das Selektieren von Daten ĂĽber
locundilocermöglicht. - pandas kopiert die Werte in einem
MultiIndexintern nicht mehr. Das verbessert die Performance und erlaubt es, die richtigen Datentypen konsistent zu verwenden.
Das pandas-Team arbeitet kontinuierlich an der Extension-Array-Schnittstelle, und jede neue Version bringt Verbesserungen mit.
Zusammenspiel mit Apache Arrow
Die Bibliothek Apache Arrow definiert ein programmiersprachenunabhängiges Format für In-Memory-Datenverarbeitungen und stellt insbesondere für String-Datentypen eine erhebliche Verbesserung im Vergleich zu NumPy und dem object-Datentyp dar.
pandas 1.5.0 führte erstmals ein auf Arrow-Arrays basiertes ExtensionArray ein. pandas 2.0 erhöht die Mindestversion der Python-Schnittstelle PyArrow und verbessert die Anbindung an Arrow deutlich. pandas 1.5.3 hat zahlreiche PerformanceWarnings ausgegeben, die anzeigten, dass eine NumPy- statt einer PyArrow-Implementierung zum Einsatz kam. Der Großteil dieser Warnung ist nun hinfällig. Außerdem hat das Team die PyArrow-Integration in den Teilen der Bibliothek verbessert, die aufgrund fehlender, spezialisierter Implementierung nicht die EA-Schnittstelle verwenden. pandas nutzt mit Version 2.0 in den meisten Fällen die korrespondierende PyArrow-Compute-Schnittstelle.
Die String-Anbindung für PyArrow-EAs entspricht im Wesentlichen der Umsetzung in älteren Extension Arrays, die durch den Datentyp string und der Option string_storage="pyarrow" aktiviert wurde.
Ein PyArrow-Datentyp lässt sich in pandas entweder durch f"{dtype}[pyarrow]", also int64[pyarrow] für Integer Datentypen, oder mit
import pandas as pd
import pyarrow as pa
dtype = pd.ArrowDtype(pa.int64)
festlegen. Diese Datentypen sind ĂĽberall erlaubt.
Der fĂĽr I/O-Funktionen neue Parameter dtype_backend dient auch zum Erzeugen DataFrames mit PyArrow-Arrays. Damit eine Funktion einen PyArrow-DataFrame zurĂĽckgibt, muss der Parameter den Wert "pyarrow" haben.
Einige I/O-Funktionen haben darĂĽber hinaus eine PyArrow-spezifische Engine, die deutlich performanter ist, weil sie nativ PyArrow-Arrays erzeugt.
Ein weiterer Vorteil von PyArrow-DataFrames ist die verbesserte Interoperabilität mit anderen Arrow-Bibliotheken. Dabei kann es sich entweder um native PyArrow-Bibliotheken handeln oder andere DataFrame-Bibliotheken wie cuDF oder Polars. Beim Konvertieren zwischen den Bibliotheken kann auf eine Kopie der Daten verzichtet werden. Marc Garcia, der Teil des pandas-core-Teams ist, hat einen Blogbeitrag verfasst, der diesen Teil genauer erläutert.
Weniger genaue Datumswerte
Bislang hat pandas alle Zeitstempel mit Nanosekunden-Präzision dargestellt. Im Folgenden entspricht asm8 der datetime-Repräsentation:
# pandas 1.5.3
In[1]: pd.Timestamp("2019-12-31").asm8
Out[1]: 2019-12-31T00:00:00.000000000
# pandas 2.0:
In[1]: pd.Timestamp("2019-12-31").asm8
Out[1]: 2019-12-31T00:00:00
Aufgrund der hohen Genauigkeit war es unmöglich, Datumswerte vor dem 21. September 1677 oder nach dem 11. April 2264 darzustellen, da die zugehörigen Werte mit Nanosekunden-Präzision die 64-bit-Integer-Grenze überschritten hätten. Alle weiteren Datumswerte haben einen Fehler zurückgegeben. Das war insbesondere für Untersuchungen über Jahrtausende oder Jahrmillionen hinderlich.
Am 10. und 11. Mai findet die Minds Mastering Machines in Karlsruhe statt. Die seit 2018 von iX, heise Developer und dpunkt.verlag ausgerichtete Fachkonferenz richtet sich in erster Linie an Data Scientists, Data Engineers und Developer, die Machine-Learning-Projekte in die Realität umsetzen.
Das Programm bietet an zwei Tagen gut 30 Vorträge unter anderem zu Sprachmodellen, Cybersecurity, Resilienz, Federate Learning, Modelloptimierung, MLOps mit Argo Workflows und dem EU AI Act.
pandas 2.0 behebt das Problem mit drei neuen Präzisionsstufen:
- Sekunden
- Millisekunden
- Mikrosekunden
Dadurch kann die Library alle Jahre zwischen -2.9e11 und 2.9e11 darstellen und beispielsweise einen Zeitstempel fĂĽr das Jahr 1000 erzeugen:
In[5]: pd.Timestamp("1000-10-11", unit="s") Out[5]: Timestamp('1000-10-11 00:00:00')
Die unterschiedlichen Präzisionsstufen steuert der Parameter unit.
Ein großer Teil von pandas ist auf Zeitstempel mit Nanosekunden-Präzision ausgelegt. Daher musste das Team die Methoden aufwendig umbauen. Da die unterschiedlichen Präzisionsgrade noch neu sind, kann es sein, dass einzelne Bereiche der API noch nicht wie gewünscht funktionieren.