Kurs
Wenn du wie ich regelmäßig Python für Datenanalysen nutzt, merkst du schnell: CSV-Dateien einlesen gehört zu den Standardaufgaben. Mit wachsenden Datensätzen kann das jedoch langsam oder speicherintensiv werden.
Polars ist eine schnelle, moderne DataFrame-Bibliothek für Python und eine leistungsstarke Alternative zu Pandas. Sie bewältigt große Datensätze deutlich flüssiger, da sie konsequent auf Geschwindigkeit und geringen Speicherverbrauch ausgelegt ist.
Die zentrale Polars-Funktion pl.read_csv() bietet eine einfache Lösung, um CSV-Dateien in ein DataFrame zu laden – mit integrierten Optionen zur Steuerung von Parsing, Datentypen und Speicherverbrauch.
In diesem Guide zeige ich dir, wie du CSV-Dateien einliest, das Parsing steuerst und große Datensätze mit der Polars-Funktion pl.read_csv() handhabst. Wenn du gerade erst startest, schau dir unseren Kurs Introduction to Polars an und lerne, wie du Daten mit Polars manipulierst und Insights gewinnst.
Grundlegende Verwendung von pl.read_csv()
Bevor wir tiefer einsteigen, wirf einen Blick auf unser Python Polars Tutorial, um deine Umgebung einzurichten.
So funktioniert die Funktion pl.read_csv():
# import the module
import polars as pl
# Load CSV into a Polars DataFrame
fuel_data = pl.read_csv("Fuel_Consumption_2000-2022.csv")
# Preview first few rows
print(fuel_data.head())
Im obigen Beispiel liest Polars die Datei und lädt sie in ein DataFrame. Die Funktion gibt ein Polars-DataFrame zurück, also eine tabellarische Datenstruktur – ähnlich wie in pandas.
Standardmäßig gilt bei pl.read_csv():
-
Die erste Zeile enthält Spaltennamen (
has_header=True). -
Spaltentypen werden automatisch erkannt.
-
Als Trennzeichen wird ein Komma (
,) verwendet. -
Die gesamte Datei wird in den Speicher geladen.
Häufig genutzte Parameter in pl.read_csv()
Nachdem du gesehen hast, wie pl.read_csv() Daten lädt, schauen wir uns an, wie du mit folgenden Parametern steuerst, wie Polars deine Daten parst.
Dateipfad und Quelle
Polars kann Daten aus verschiedenen Quellen laden. Du kannst einen lokalen String-Pfad, ein Pathlib-Objekt oder sogar eine URL übergeben. Das folgende Beispiel liest eine große CSV-Datei aus dem Web mit BIP-Daten verschiedener Länder über mehrere Jahre.
# Reading from a URL
url = "https://raw.githubusercontent.com/datasets/gdp/master/data/gdp.csv"
gdp_data = pl.read_csv(url)
Trennzeichen und Separatoren
Nicht alle CSV-Dateien nutzen Kommas. Über das Argument separator kannst du Tabs, Semikolons, Pipes oder andere Zeichen angeben. Das folgende Beispiel zeigt, wie du beim Einlesen das Trennzeichen festlegst.
# Reading a Semicolon-separated file
sales_data = pl.read_csv("2024_sales.csv", separator=";")
# Reading a Tab-separated file (TSV)
orders_data = pl.read_csv("all_orders.tsv", separator="\t")
Header-Behandlung
Wie bereits gesehen, geht Polars davon aus, dass die erste Zeile Spaltennamen enthält. Falls deine Datei keine Kopfzeile hat, setze has_header=False, wie unten gezeigt. Polars weist dann automatisch Spaltennamen wie column_1, column_2, column_3 usw. zu.
# Load file without a header
orders_data = pl.read_csv("all_orders.csv", has_header=False)
Du kannst Spalten auch durch Übergabe konkreter Namen umbenennen. Zum Beispiel:
# Providing specific column names
sales_data = pl.read_csv("sales_April.csv", new_columns=[
"OrderDate", "OrderNumber", "ProductKey", "SalespersonKey", "Salesperson"])
Zeichenkodierung
Verschiedene CSV-Dateien können unterschiedliche Textkodierungen verwenden. Wenn du auf merkwürdige Zeichen oder Fehler stößt, gib die Kodierung an:
# Load CSV into a Polars DataFrame
fuel_data = pl.read_csv("Fuel_Consumption_2000-2022.csv", encoding="utf8")
Weitere gängige Optionen sind "latin1" und "utf8-lossy", die ungültige Zeichen passend behandeln.
Spalten beim Einlesen in Polars auswählen
Bei großen CSV-Dateien brauchst du oft nicht alle Spalten. Mit dem Parameter columns kannst du nur die gewünschten Spalten laden.
# Load only specific columns
fuel_data = pl.read_csv("Fuel_Consumption_2000-2022.csv",
columns=["YEAR", "MAKE", "MODEL"]
)
Wenn du die benötigten Spalten bereits beim Laden auswählst, sinkt der Speicherbedarf, da unnötige Daten gar nicht erst eingelesen werden. Das beschleunigt das Einlesen und verbessert die Performance deiner Pipeline insgesamt.
Datentypen (Schema) in Polars-CSV steuern
Polars ist stark typisiert, das heißt, jede Spalte hat einen konsistenten Datentyp, z. B. nur Ganzzahlen oder nur Strings.
Automatische Typinferenz
Standardmäßig untersucht Polars deine Daten und bestimmt die Spaltentypen automatisch. Das funktioniert meist gut, kann aber gelegentlich Spalten fehlinterpretieren, etwa wenn IDs als Ganzzahlen statt als Strings behandelt werden.
Schema manuell festlegen
Wenn du Konsistenz im DataFrame sicherstellen willst, gib das Datenschema manuell an. So erzielst du einheitliche Typen über mehrere Dateien hinweg und vermeidest Typfehler in nachgelagerten Schritten.
In den meisten Fällen nutzt du schema_overrides, um die Datentypen bestimmter Spalten festzulegen und die übrigen weiterhin automatisch erkennen zu lassen.
import polars as pl
# Manually overriding specific data types
empl_data = pl.read_csv(
"all_employees.csv",
schema_overrides={
"id": pl.Int64,
"name": pl.String,
"age": pl.Int64,
"salary": pl.Float64
}
)
Oder du nutzt schema, um die gesamte Struktur des DataFrames zu definieren.
# Manually define the full schema
empl_data = pl.read_csv(
"all_employees.csv",
schema={
"id": pl.Int64,
"name": pl.String,
"age": pl.Int64,
"salary": pl.Float64
}
)
Fehlende Werte in Polars-CSV behandeln
Standardmäßig erkennt Polars fehlende Werte automatisch und stellt sie als null dar. Manchmal werden fehlende Werte durch bestimmte Strings dargestellt, etwa "NA", "N/A" oder "missing". Mit null_values kannst du solche Marker definieren, damit sie als null behandelt werden.
# Treating "N/A" and "EMPTY" as nulls
survey_data = pl.read_csv(
"survey_results.csv",
null_values=["N/A", "EMPTY", "null"]
)
Wenn du fehlende Werte sauber behandelst, bleiben Datentypen konsistent und fehlerhafte Berechnungen werden vermieden – das reduziert Fehler in Analyse und Modellierung.
Große CSV-Dateien mit Polars einlesen
Bei großen Datensätzen, die deinen verfügbaren RAM übersteigen, zeigt Polars seine Stärken: Es verarbeitet Daten, ohne die gesamte Datei auf einmal zu laden.
Lazy Loading mit scan_csv()
Anstatt Daten wie bei read_csv() sofort in den Speicher zu laden, bietet Polars mit scan_csv() eine Lazy-Alternative, die einen optimierten Abfrageplan erstellt und nur die nötigen Operationen ausführt.
Im folgenden Beispiel scannt pl.scan_csv die CSV-Datei, ohne sie zu laden, erstellt eine Abfrage, die nur die Spalten „YEAR“, „MAKE“ und „MODEL“ für die Automarke „ACURA“ holt, und führt diese dann aus. So wird nur der gefilterte Datenausschnitt in den Speicher geladen – nicht die ganze Datei.
# Lazily reference the file (no data loaded yet)
fuel_consumption = pl.scan_csv("Fuel_Consumption_2000-2022.csv")
fuel_consumption_filtered = fuel_consumption.select(
["YEAR", "MAKE", "MODEL"]).filter(pl.col("MAKE") == "ACURA")
# Execute the query and load only the required data
fuel_consumption_acura = fuel_consumption_filtered.collect()
Ich empfehle, scan_csv() zu verwenden, wenn:
- Du mit großen Dateien arbeitest, die nicht entspannt in den Speicher passen.
- Du mehrere Transformationen wie Filtern, Auswählen und Aggregieren anwendest.
- Du vor der Ausführung eine Abfrageoptimierung möchtest.
Streaming und Speichereffizienz
Polars kann Daten auch streamen und in Batches verarbeiten, wodurch der maximale Speicherbedarf unabhängig von der Dateigröße konstant bleibt.
Für große CSV-Dateien startest du mit scan_csv(), um eine Lazy-Abfrage zu erstellen. Beim Aufruf von scan_csv() wird die Datei noch nicht vollständig geladen.
# Read data in chunks
fuel_consumption = pl.scan_csv("Fuel_Consumption_2000-2022.csv",
low_memory=True)
Da die oben genannte Methode intern weiterhin read_csv nutzt, fährst du am besten, wenn du Lazy Execution mit Streaming kombinierst.
Im folgenden Beispiel verarbeitet Polars die Datei in einer Pipeline batchweise zeilenweise und hält jeweils nur die gefilterten Zeilen (wo "CYLINDERS" > 3) im Speicher.
# Lazily reference the file (no data loaded yet)
fuel_consumption = pl.scan_csv("Fuel_Consumption_2000-2022.csv")
result = fuel_consumption.filter(pl.col("CYLINDERS") > 3)
# Stream execution instead of loading everything at once
fuel_consumption_high = result.collect(engine="streaming")
Performancevorteil gegenüber Pandas
Im Vergleich zu pandas ist Polars beim Einlesen und Verarbeiten von CSVs oft schneller, wie wir im nächsten Abschnitt sehen.
Polars read_csv vs. Pandas read_csv
Die folgende Tabelle fasst die Unterschiede zwischen Polars und Pandas beim Einlesen von CSV in Python zusammen.
|
Aspekt |
Polars |
Pandas |
|
Geschwindigkeit |
Schneller dank Multithreading und optimiertem Parsing |
Langsamer bei großen Dateien (meist single-threaded) |
|
Speicherauslastung |
Geringerer Footprint; unterstützt Lazy + Streaming |
Lädt den gesamten Datensatz sofort in den Speicher |
|
Syntax |
|
|
|
Ausführungsmodell |
Unterstützt Lazy Execution ( |
Nur eager (sofortige) Ausführung |
|
Optimierung |
Integrierte Abfrageoptimierung (Projektion, Filter) |
Begrenzte automatische Optimierung |
|
Optimaler Einsatz |
Große Datensätze, performancekritische Workflows |
Kleinere Datensätze, schnelle Analysen |
Ich empfehle, unseren Artikel zu den Unterschieden zwischen Pandas vs. Polars zu lesen, um das passende Tool für deine Analytics-Bedürfnisse zu wählen.
CSV aus verschiedenen Quellen lesen
Wie bereits gezeigt, kannst du mit Polars CSV-Dateien aus unterschiedlichen Quellen lesen. In den obigen Beispielen habe ich gezeigt, wie du CSVs aus lokalen Dateien und aus URLs einliest.
Zusätzlich kann Polars komprimierte CSV-Dateien automatisch handhaben. Das folgende Beispiel liest Daten aus einer .gzip-Datei.
# Read gzip-compressed CSV
census_data = pl.read_csv("2018_census.csv.gz")
Häufige Fehler und Troubleshooting
Auch mit einer Hochleistungs-Engine wie Polars können beim Einlesen von CSV-Dateien Probleme auftreten. Hier sind einige häufige Stolpersteine aus meiner Praxis und wie du sie behebst.
-
Encoding-Fehler: Du siehst ggf. einen
UnicodeDecodeError. Das bedeutet, die Datei nutzt kein UTF-8 – häufig bei älteren Dateien oder CSVs aus bestimmten Excel-Versionen. Löse das, indem du die passende Kodierung setzt oder"utf8-lossy"verwendest, wenn die Datei inkonsistente oder defekte Zeichen enthält. -
Probleme mit Trennzeichen: Wenn dein DataFrame lädt, aber alle Daten in einer einzigen Spalte landen, hat Polars das Trennzeichen nicht erkannt. Setze das korrekte Trennzeichen explizit über
separator, z. B. Semikolon (;), Tab (\t) oder Pipe (|). -
Falsche Datentypen: Mitunter erkennt Polars Typen falsch, etwa wenn numerische IDs als Strings gelesen werden oder Parsing-Fehler auftreten. Nutze dann
schema_overrides, um bestimmte Spaltentypen festzulegen. Wenn du alle Spaltentypen definieren willst, verwendeschema. Du kannst auchinfer_schema_lengtherhöhen, damit Polars vor der Typinferenz mehr Zeilen prüft. -
Speicherprobleme bei großen Dateien: Wenn dein Python-Prozess beim Laden großer Dateien abstürzt, ist dein RAM erschöpft. Wechsle auf
scan_csv()für Lazy Loading, um Speicherbedarf zu senken und Performance zu verbessern. Du kannst außerdem weniger Spalten laden oder mit Streaming in Batches arbeiten.
Fazit
Die Funktion read_csv() in Polars ist einfach zu nutzen und gleichzeitig stark genug für Aufgaben aus der Praxis. Aus meiner Sicht hat Polars bei wachsenden Datensätzen klare Vorteile.
Als nächsten Schritt lies unseren Blog zur Polars GPU engine, um mehr über die unterschiedlichen Einsatzszenarien zu erfahren. Wenn du direkt praktisch werden willst, begleitet dich unser Super Bowl Analytics with Polars Code-Along dabei, reale Analysefragen zu lösen, Berechnungen anzuwenden und grundlegende ML-Techniken in der Sportanalytik einzusetzen.
FAQs
Was ist der Unterschied zwischen read_csv() und scan_csv() in Polars?
read_csv() lädt Daten sofort in den Speicher (eager), während scan_csv() Lazy Execution nutzt und Daten erst beim Aufruf von .collect() verarbeitet.
Wann sollte ich scan_csv() statt read_csv() verwenden?
Nutze scan_csv() für große Datensätze oder beim Verketten mehrerer Transformationen, da es die Ausführung optimiert und den Speicherbedarf reduziert.
Kann Polars nur bestimmte Spalten aus einer CSV-Datei lesen?
Ja, nutze den Parameter columns=[...] in read_csv() oder wähle Spalten in einer Lazy-Abfrage mit scan_csv() aus.
Wie gehe ich in Polars-CSV-Dateien mit fehlenden Werten um?
Polars behandelt leere Werte standardmäßig als null. Eigene Null-Marker kannst du über null_values= definieren.
Unterstützt Polars komprimierte CSV-Dateien?
Ja, komprimierte Formate wie .gz und .zip werden ohne manuelles Entpacken unterstützt.
