Data Science

Polars und pandas: Was ist der Unterschied?

Read this post in other languages:

Wenn Sie im vergangenen Jahr die Entwicklung bei Python-Dataframes verfolgt haben, haben Sie mit Sicherheit schon von Polars gehört, der leistungsstarken Dataframe-Bibliothek für große Datensammlungen.


Polars in DataSpell ausprobieren

Im Gegensatz zu anderen Bibliotheken für große Datensammlungen wie Spark, Dask und Ray ist Polars für die Nutzung auf einem einzigen Rechner konzipiert, weswegen es oft mit pandas verglichen wird. Polars unterscheidet sich jedoch in wichtigen Punkten von pandas, unter anderem in der Art und Weise der Arbeit mit Daten sowie den optimalen Einsatzgebieten. Im folgenden Artikel gehen wir auf die technischen Details ein, die diese beiden Dataframe-Bibliotheken voneinander unterscheiden, und wir werfen einen Blick auf die Stärken und Beschränkungen beider Bibliotheken.

Um mehr über das Thema zu erfahren, sehen Sie sich unten unser Interview mit Polars-Schöpfer Ritchie Vink an!

Warum Polars statt pandas verwenden?

Mit einem Wort: Performance. Polars wurde von Grund auf für Schnelligkeit entwickelt, sodass es gängige Operationen etwa 5- bis 10-mal schneller als pandas ausführt. Darüber hinaus ist der Speicherbedarf von Operationen in Polars deutlich geringer als bei pandas: pandas benötigt für die Durchführung von Operationen etwa 5- bis 10-mal mehr Arbeitsspeicher als die Größe des Datensatzes, während Polars sich mit dem 2- bis 4-Fachen genügt.

Hier erhalten Sie einen Eindruck davon, wie Polars im Vergleich zu anderen Dataframe-Bibliotheken abschneidet. Wie Sie sehen können, ist Polars bei gängigen Operationen 10- bis 100-mal schneller als pandas und eine der schnellsten Dataframe-Bibliotheken überhaupt. Außerdem kann es größere Datensammlungen als pandas verarbeiten, bevor ihm der Arbeitsspeicher ausgeht.

Warum ist Polars so schnell?

Angesichts dieser äußerst beeindruckenden Ergebnisse fragen Sie sich vielleicht: Wie kann Polars trotz der Ausführung auf einem einzigen Rechner diese Performance erzielen? Bei der Entwicklung der Bibliothek wurde von Anfang an auf Leistung geachtet, und dabei kamen unterschiedliche Mittel zum Einsatz.

Geschrieben in Rust

Einer der bekanntesten Fakten über Polars ist, dass es in Rust geschrieben ist, einer Low-Level-Sprache, deren Geschwindigkeit fast an C und C++ herankommt. pandas hingegen basiert auf Python-Bibliotheken, unter anderem auf NumPy. Zwar ist der Kern von NumPy in C geschrieben, es wird aber trotzdem durch inhärente Probleme eingebremst, die mit der Art und Weise zu tun haben, wie Python bestimmte Typen im Arbeitsspeicher handhabt – zum Beispiel Zeichenfolgen für Kategoriedaten. Dies führt zu einer schlechten Leistung beim Umgang mit diesen Typen (weitere Details finden Sie in einem fantastischen Blogartikel von Wes McKinney).

Ein weiterer Vorteil von Rust ist, dass es sichere Nebenläufigkeit ermöglicht, d. h. es ist darauf ausgelegt, Parallelität so vorhersehbar wie möglich zu machen. Dadurch kann Polars auch bei komplexen Abfragen mit mehreren Spalten alle Kerne Ihres Systems nutzen – nicht umsonst nannte Ritchie Vink Polars „hochgradig parallel“. Dies verleiht Polars einen enormen Leistungsvorteil gegenüber pandas, das zur Ausführung von Operationen nur einen Kern verwendet. In diesem hervorragenden Vortrag auf der diesjährigen PyCon DE geht Nico Kreiling genauer darauf ein, wie Polars dies erreicht.

Basierend auf Arrow

Ein weiterer Faktor, der zur beeindruckenden Performance von Polars beiträgt, ist das sprachunabhängige Speicherformat Apache Arrow. Arrow wurde von Wes McKinney als Antwort auf viele Probleme entwickelt, die er bei pandas bei explodierenden Datenmengen erkannte. Es dient auch als Backend für pandas 2.0, eine leistungsfähigere pandas-Version, die im März dieses Jahres veröffentlicht wurde. Die Arrow-Backends der Bibliotheken unterscheiden sich jedoch leicht: Während pandas 2.0 auf PyArrow aufbaut, hat das Polars-Team seine eigene Arrow-Implementierung gebaut.

Einer der Hauptvorteile beim Aufbau einer Datenbibliothek auf der Basis von Arrow ist die Interoperabilität. Arrow wurde entwickelt, um das Format der In-Memory-Daten über Bibliotheken hinweg zu standardisieren, und wie Sie unten sehen können, wird es bereits von mehreren wichtigen Bibliotheken und Datenbanken verwendet.

Diese Interoperabilität erhöht die Performance, da die Daten nicht mehr in unterschiedliche Formate konvertiert werden müssen, wenn sie von einem Pipeline-Schritt zum nächsten weitergeleitet werden (anders ausgedrückt ist es nicht mehr notwendig, die Daten zu serialisieren und zu deserialisieren). Es ist auch speichereffizienter, da zwei Prozesse dieselben Daten gemeinsam nutzen können, ohne eine Kopie erstellen zu müssen. Da die Serialisierung/Deserialisierung bei Daten-Workflows ca. 80–90% des Rechenaufwands ausmacht, verhilft das universelle Arrow-Datenformat Polars zu erheblichen Leistungsgewinnen.

Arrow bietet außerdem integrierte Unterstützung für eine breitere Palette von Datentypen als pandas. Da pandas auf NumPy basiert, kann es hervorragend mit Ganzzahl- und Fließkommazahl-Spalten umgehen, hat jedoch Schwierigkeiten bei anderen Datentypen. Im Gegensatz dazu bietet Arrow umfassende Unterstützung für Spalten mit Datums-, booleschen und Binärwerten und sogar komplexe Spaltentypen, etwa solche, die Listen enthalten. Außerdem kann Arrow nativ mit fehlenden Daten umgehen, während in NumPy ein Workaround erforderlich ist.

Und schließlich verwendet Arrow eine spaltenbasierte Datenspeicherung. Dies bedeutet, dass unabhängig vom Datentyp alle Spalten in einem kontinuierlichen Speicherblock gespeichert werden. Dies vereinfacht nicht nur die Parallelisierung, sondern beschleunigt auch den Datenabruf.

Abfrageoptimierung

Ein weiterer Kernaspekt der Polars-Performance ist die Art und Weise, wie Code ausgewertet wird. pandas setzt standardmäßig die sogenannte Eager Execution ein, die Operationen werden also in der Reihenfolge ausgeführt, in der Sie sie geschrieben haben. Im Gegensatz dazu ist Polars in der Lage, neben Eager Execution auch Lazy Execution zu verwenden, wobei ein Abfrageoptimierer alle erforderlichen Operationen auswertet und den effizientesten Weg zur Ausführung des Codes findet. Dies kann unter anderem das Ändern der Ausführungsreihenfolge von Operationen oder den Verzicht auf redundante Berechnungen beinhalten. Nehmen wir zum Beispiel den folgenden Ausdruck, der jeweils den Mittelwert der Spalte Number1 für die Kategorien „A“ und „B“ in Category berechnet.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
(
df
.groupby(by = "Category").agg(pl.col("Number1").mean())
.filter(pl.col("Category").is_in(["A", "B"]))
)
( df .groupby(by = "Category").agg(pl.col("Number1").mean()) .filter(pl.col("Category").is_in(["A", "B"])) )
(
df
.groupby(by = "Category").agg(pl.col("Number1").mean())
.filter(pl.col("Category").is_in(["A", "B"]))
)

Bei Eager Execution wird die groupby-Operation unnötigerweise für den gesamten DataFrame ausgeführt, und erst danach wird nach Category gefiltert. Bei Lazy Execution kann der DataFrame gefiltert und groupby nur auf die relevanten Daten angewendet werden.

Ausdrucksstarke API

Polars verfügt über eine extrem ausdrucksstarke API. Dies bedeutet, dass im Grunde jede benötigte Operation als Polars-Methode ausgedrückt werden kann. Im Gegensatz dazu müssen komplexere Operationen in pandas oft als Lambda-Ausdruck an die Methode apply übergeben werden. Das Problem mit apply ist, dass sie in einer Schleife auf die Zeilen des DataFrames angewendet wird, die Operation wird also nacheinander für jede Zeile ausführt. Durch die Verwendung eingebauter Methoden können Sie spaltenbasiert arbeiten und SIMD, eine andere Form der Nebenläufigkeit, nutzen.

Wann ist pandas zu bevorzugen?

Das bisher Gesagte klingt so eindrucksvoll, dass Sie sich wahrscheinlich fragen, warum Sie sich überhaupt noch mit pandas abgeben sollten. So einfach ist es jedoch nicht. Polars eignet sich zwar hervorragend für hocheffiziente Datentransformationen, ist aber derzeit nicht die optimale Wahl für die Datenexploration oder für den Einsatz in Pipelines für maschinelles Lernen (ML). In diesen Bereichen liegt pandas weiterhin vorn.

Einer der Gründe dafür ist, dass Polars zwar eine große Interoperabilität mit anderen Arrow-basierten Paketen bietet, aber noch nicht mit den meisten Python-Paketen zur Datenvisualisierung oder ML-Bibliotheken wie scikit-learn und PyTorch kompatibel ist. Die einzige Ausnahme ist Plotly, mit dem Sie Diagramme direkt aus Polars-DataFrames erstellen können.

Eine aktuell diskutierte Lösung wäre die Verwendung des Python-Dataframe-Austauschprotokolls in diesen Paketen, um ihnen die Unterstützung unterschiedlicher Dataframe-Bibliotheken zu ermöglichen. Dadurch würden Data-Science- und ML-Workflows nicht mehr durch pandas eingebremst werden. Dies ist jedoch eine relativ neue Idee, und die Umsetzung dieser Projekte wird einige Zeit dauern.

Tools für Polars und pandas

Nach all dem können Sie es sicher kaum erwarten, Polars eigenhändig auszuprobieren! Sowohl DataSpell als auch PyCharm Professional 2023.2 bieten hervorragende Werkzeuge für die Arbeit mit pandas und Polars in Jupyter-Notebooks. So stehen Ihnen insbesondere bei der Visualisierung von pandas- und Polars-DataFrames interaktive Funktionen zur Verfügung, mit denen Sie Ihre Daten viel schneller und bequemer erkunden können.

Zu meinen Lieblingsfunktionen gehören das Blättern durch alle Zeilen und Spalten des DataFrames, ohne dass diese abgeschnitten werden, Ein-Klick-Aggregationen von DataFrame-Werten sowie die Möglichkeit, DataFrames in einer Vielzahl von Formaten zu exportieren (einschließlich Markdown!).

Wenn Sie DataSpell noch nicht nutzen, können Sie es im Rahmen einer 30-tägigen Testphase ausprobieren, indem Sie dem nachstehenden Link folgen.


Probieren Sie es jetzt aus!

Autorin des Original-Blogposts:

Jodie Burchell

Jodie Burchell

Dr. Jodie Burchell is the Developer Advocate in Data Science at JetBrains, and was previously a Lead Data Scientist at Verve Group Europe. She completed a PhD in clinical psychology and a postdoc in biostatistics, before leaving academia for a data science career. She has worked for 7 years as a data scientist in both Australia and Germany, developing a range of products including recommendation systems, analysis platforms, search engine improvements and audience profiling. She has held a broad range of responsibilities in her career, doing everything from data analytics to maintaining machine learning solutions in production. She is a long time content creator in data science, across conference and user group presentations, books, webinars, and posts on both her own and JetBrain’s blogs.

image description

Discover more