HOWTO · Pandas
chunksize in Pandas
Dieses Tutorial behandelt den chunksize-Parameter in Python.
Auf dieser Seite
Die Bibliothek pandas organisiert Daten in DataFrames aus Zeilen und Spalten, und Reader wie read_csv laden eine Datei normalerweise vollständig in einen einzigen DataFrame. Wenn eine Datei zu groß ist, um sie bequem zu laden — etwa ein Datensatz wie der MovieLens-Bewertungsdatensatz mit Millionen von Zeilen —, können Sie sie mit dem Parameter chunksize stattdessen in Zeilenbatches lesen und verarbeiten.
So funktioniert chunksize in pandas
Wenn Sie chunksize=n an einen unterstützten pandas-Reader übergeben, ändert sich dessen Rückgabewert: Statt eines DataFrame liefert read_csv() einen TextFileReader — ein iteratorähnliches Objekt, das pro Batch einen DataFrame zurückgibt. Jeder Batch enthält höchstens n Zeilen, und der letzte Batch kann weniger enthalten, wenn die Zeilenzahl kein exaktes Vielfaches der Chunk-Größe ist.
Zwei Details sind beim Übernehmen dieses Musters wichtig. Erstens zählt chunksize Zeilen, nicht Bytes: Jeder Chunk behält alle Spalten der Datei, nur die Zeilenzahl variiert. Zweitens macht der Parameter das Parsen nicht von sich aus schneller. Er ändert, wann Speicher reserviert wird; ob er hilft, hängt also davon ab, was Ihr Programm aus jedem Chunk behält.
Eine CSV-Datei in Chunks lesen
Um eine Datei in Batches zu lesen, übergeben Sie chunksize an read_csv und iterieren über das Ergebnis. Das folgende Beispiel schreibt eine kleine CSV-Datei im Ratings-Stil in eine temporäre Datei und liest sie anschließend mit drei Zeilen pro Batch wieder ein; dabei wird die shape jedes gelieferten DataFrames ausgegeben, damit Sie die Batch-Aufteilung sehen können.
Führen Sie dieses Beispiel aus:
Der Code und die angezeigten Bezeichnungen oder Ausgaben in diesem Abschnitt bleiben auf Englisch.
import os
import tempfile
import pandas as pd
rows = ["userId,movieId,rating"]
for i in range(7):
rows.append(f"{i + 1},{100 + i},{1.0 + (i % 5) * 0.5}")
path = os.path.join(tempfile.mkdtemp(), "ratings.csv")
with open(path, "w") as f:
f.write("\n".join(rows) + "\n")
reader = pd.read_csv(path, chunksize=3)
for number, chunk in enumerate(reader, start=1):
print(f"chunk {number}: shape={chunk.shape}")
chunk 1: shape=(3, 3)
chunk 2: shape=(3, 3)
chunk 3: shape=(1, 3)
Die Datei enthält sieben Datenzeilen, und chunksize=3 bewirkt, dass der TextFileReader zwei volle Chunks und anschließend einen Rest-Chunk mit einer Zeile liefert. Die Spaltenzahl bleibt bei jedem Chunk drei — die Batch-Aufteilung betrifft also nur die Zeilen.
Jeden Chunk verarbeiten
Das sinnvolle Muster besteht darin, pro Chunk ein kleines Ergebnis zu akkumulieren — etwa eine Anzahl, eine Summe oder eine gefilterte Teilmenge —, statt die Chunks selbst zu sammeln. Dieses Beispiel aggregiert dieselbe Datei und führt eine laufende Zeilenzahl sowie die Summe der Bewertungen mit, sodass die gesamte Datei nie vollständig im Speicher liegen muss.
Führen Sie dieses Beispiel aus:
Der Code und die angezeigten Bezeichnungen oder Ausgaben in diesem Abschnitt bleiben auf Englisch.
import os
import tempfile
import pandas as pd
rows = ["userId,movieId,rating"]
for i in range(7):
rows.append(f"{i + 1},{100 + i},{1.0 + (i % 5) * 0.5}")
path = os.path.join(tempfile.mkdtemp(), "ratings.csv")
with open(path, "w") as f:
f.write("\n".join(rows) + "\n")
total_rows = 0
rating_sum = 0.0
for chunk in pd.read_csv(path, chunksize=3):
total_rows += len(chunk)
rating_sum += chunk["rating"].sum()
print(f"rows read: {total_rows}")
print(f"average rating: {rating_sum / total_rows:.2f}")
rows read: 7
average rating: 1.79
Innerhalb der Schleife funktioniert jede DataFrame-Operation — Filtern, Spaltenauswahl oder groupby-Aggregationen —, sodass Sie jeden Chunk transformieren können, bevor Sie ihn in den Akkumulator einfließen lassen.
Chunk-Größe und Speicher-Trade-offs verstehen
Das Lesen in Chunks kann den Spitzenwert des Speicherverbrauchs senken, aber nicht automatisch. Der Spitzenverbrauch entspricht ungefähr der Größe des größten Chunks plus allem, was Ihr Programm darüber hinaus behält. Wenn Sie jeden Chunk an eine Liste anhängen und anschließend alle zusammenfügen, halten Sie wieder den gesamten Datensatz im Speicher und können mehr verbrauchen als bei einem einzigen normalen Lesevorgang.
Wählen Sie den Wert als Ausgleich zweier Gegenkräfte. Ein größerer chunksize bedeutet weniger Schleifendurchläufe und weniger Overhead pro Iteration, belegt aber pro Chunk mehr Speicher. Ein kleinerer Wert senkt den Spitzenverbrauch auf Kosten zusätzlicher Schleifendurchläufe. Schreiben Sie außerdem Schleifencode, der keine feste Zeilenzahl voraussetzt, da der letzte Chunk in der Regel kürzer ist.
Chunkweises Lesen mit anderen Datenquellen
chunksize ist nicht auf read_csv beschränkt. Weitere pandas-Reader, die den Parameter akzeptieren, sind pandas.read_json (mit lines=True), pandas.read_sql und pandas.read_sql_table, pandas.read_stata sowie pandas.read_sas; einige Reader wie pandas.read_hdf bieten stattdessen einen gleichwertigen iterator-Modus. Die Unterstützung und die akzeptierten Optionen variieren je nach Reader und pandas-Version — prüfen Sie daher die offizielle Dokumentation der Funktion, die Sie verwenden möchten.
Das Muster bleibt überall dort gleich, wo chunkweises Lesen verfügbar ist: Batches anfordern, darüber iterieren und jeden Batch zu einem kleinen Ergebnis zusammenführen.