Menu
CoddyTech

Pandas Cheat Sheet

Zuletzt aktualisiert

DataFrame erstellen

Kleine DataFrames von Hand gebaut, für Beispiele, Tests und Lookup-Tabellen.

AufgabeCode
pandas und NumPy importierenimport pandas as pd import numpy as np
Aus einem Dict von Spaltendf = pd.DataFrame({"name": ["Ada", "Ben"], "age": [36, 28]})
Aus einer Liste von Zeilenpd.DataFrame([{"name": "Ada", "age": 36}, {"name": "Ben", "age": 28}])
Aus einem NumPy-Arraypd.DataFrame(np.arange(6).reshape(3, 2), columns=["x", "y"])
Eine Series mit Labelss = pd.Series([3, 5, 2], index=["a", "b", "c"])
Ein Datumsbereichpd.date_range("2026-01-01", periods=7, freq="D")

Dateien lesen und schreiben

Ein Aufruf lädt eine Datei in einen DataFrame, ein Aufruf schreibt sie zurück.

AufgabeCode
CSV-Datei lesendf = pd.read_csv("sales.csv")
Nur einige Spalten, mit echten Datumswertenpd.read_csv("sales.csv", usecols=["date", "city", "sales"], parse_dates=["date"])
Spalte als Index verwendenpd.read_csv("sales.csv", index_col="id")
Tab oder anderes Trennzeichenpd.read_csv("sales.tsv", sep="\t")
Weitere Marker als fehlend wertenpd.read_csv("sales.csv", na_values=["n/a", "-"])
Nur die ersten Zeilen lesenpd.read_csv("sales.csv", nrows=1000)
Excel-Blatt lesen (braucht openpyxl)pd.read_excel("report.xlsx", sheet_name="2026")
JSON-Records lesenpd.read_json("records.json")
Aus einer SQL-Datenbank lesenpd.read_sql("SELECT * FROM orders", conn)
CSV ohne Index schreibendf.to_csv("clean.csv", index=False)
Excel oder Parquet schreibendf.to_excel("clean.xlsx", index=False), df.to_parquet("clean.parquet")

Daten untersuchen

Die ersten Aufrufe für jeden neuen Datensatz.

AufgabeCode
Erste und letzte Zeilendf.head(), df.tail(3)
Anzahl Zeilen und Spaltendf.shape # (6, 7)
Spaltentypen und Nicht-Null-Wertedf.info()
Kennzahlen der numerischen Spaltendf.describe()
Übersicht über alle Spaltendf.describe(include="all")
Spaltennamen und Typendf.columns, df.dtypes
Jeden Wert zählendf["city"].value_counts()
Anteil jedes Wertsdf["city"].value_counts(normalize=True)
Eindeutige Werte und ihre Anzahldf["city"].unique(), df["city"].nunique()
Fehlende Werte pro Spaltedf.isna().sum()
Zufällige Stichprobe von Zeilendf.sample(3, random_state=0)
Korrelation numerischer Spaltendf.corr(numeric_only=True)

Spalten und Zeilen auswählen

loc wählt nach Label aus und schließt das Ende eines Slice ein. iloc wählt nach Position aus und schließt es aus.

AufgabeCode
Eine Spalte als Seriesdf["age"]
Mehrere Spalten als DataFramedf[["name", "age"]]
Zeilen und Spalten nach Labeldf.loc[0:2, ["name", "age"]]
Zeilen und Spalten nach Positiondf.iloc[0:2, 0:3]
Ein einzelner Wertdf.at[0, "age"], df.iat[0, 3]
Letzte Zeiledf.iloc[-1]
Spalten eines Typsdf.select_dtypes(include="number")
Textspalten (pandas 3)df.select_dtypes(include="str")
Spalten nach Namensmusterdf.filter(like="sal"), df.filter(regex="^(age|salary)$")
Zeilen über eine Spalte nachschlagendf.set_index("name").loc["Ada", "salary"]
Zurück zum Index 0, 1, 2df.reset_index(drop=True)
Spalten oder Zeilen entfernendf.drop(columns=["email"]), df.drop(index=[0, 1])

Zeilen filtern

Setze jede Bedingung in Klammern und verknüpfe sie mit & (und), | (oder) und ~ (nicht).

AufgabeCode
Zeilen, die eine Bedingung erfüllendf[df["age"] > 30]
Beide Bedingungendf[(df["age"] > 30) & (df["city"] == "Oslo")]
Eine der Bedingungendf[(df["city"] == "Oslo") | (df["salary"] > 6000)]
Wert in einer Listedf[df["city"].isin(["Oslo", "Rome"])]
Wert nicht in einer Listedf[~df["city"].isin(["Oslo", "Rome"])]
Zwischen zwei Werten, Grenzen inklusivedf[df["age"].between(30, 40)]
Mit einem Query-String filterndf.query("age > 30 and city == 'Oslo'")
Variable in einer Query nutzenmin_age = 30 df.query("age > @min_age")
Text enthältdf[df["name"].str.contains("e", case=False)]
Fehlende oder vorhandene Wertedf[df["age"].isna()], df[df["age"].notna()]
Zeilen filtern und Spalten wählendf.loc[df["age"] > 30, ["name", "salary"]]
Größte oder kleinste n Zeilendf.nlargest(3, "salary"), df.nsmallest(2, "age")
Zeilen mit doppeltem Wertdf[df.duplicated(subset=["city"], keep=False)]

Sortieren und ranken

AufgabeCode
Nach einer Spalte sortierendf.sort_values("salary")
Größte zuerstdf.sort_values("salary", ascending=False)
Nach mehreren Spalten sortierendf.sort_values(["city", "salary"], ascending=[True, False])
Fehlende Werte zuerstdf.sort_values("age", na_position="first")
Nach dem Index sortierendf.sort_index()
Werte ranken, 1 ist der höchstedf["salary"].rank(ascending=False)

Spalten hinzufügen und ändern

Operationen auf ganzen Spalten sind schnell. Greif nur zu apply, wenn keine eingebaute Methode die Aufgabe erledigt.

AufgabeCode
Neue Spalte aus anderendf["bonus"] = df["salary"] * 0.1
Spalte in einer Kette hinzufügendf.assign(bonus=lambda d: d["salary"] * 0.1)
Wert aus einer Bedingungdf["level"] = np.where(df["age"] >= 40, "senior", "junior")
Wert aus mehreren Bedingungendf["band"] = np.select([df["age"] < 30, df["age"] < 45], ["young", "mid"], default="senior")
Werte ändern, wo eine Bedingung giltdf.loc[df["city"] == "Lima", "salary"] = 4000
Werte per Dict zuordnendf["country"] = df["city"].map({"Oslo": "NO", "Rome": "IT", "Lima": "PE"})
Funktion auf eine Spalte anwendendf["salary"].apply(lambda x: round(x, -3))
Funktion auf jede Zelle anwendendf[["age", "salary"]].map(lambda x: x / 1000)
Spalten umbenennendf.rename(columns={"salary": "pay"})
Spaltentyp änderndf["salary"].astype("float64")
Text in Zahlen, ungültige Werte zu NaNpd.to_numeric(s, errors="coerce")
Zahlen in benannte Klassenpd.cut(df["age"], bins=[0, 30, 45, 120], labels=["young", "mid", "senior"])
Zahlen in gleich große Gruppenpd.qcut(df["salary"], q=4, labels=False)
Über Zeilen iterieren (langsam, letzter Ausweg)for row in df.itertuples(): print(row.name, row.salary)

Fehlende Werte und Bereinigung

Fehlende Zahlen erscheinen als NaN, fehlende Datumswerte als NaT. Jeder dieser Aufrufe gibt ein neues Objekt zurück, also weise das Ergebnis zu.

AufgabeCode
Anteil fehlender Werte pro Spaltedf.isna().mean()
Zeilen mit fehlendem Wert entfernendf.dropna()
Zeilen ohne Schlüsselspalte entfernendf.dropna(subset=["age"])
Mit einem Wert pro Spalte füllendf.fillna({"age": df["age"].median()})
Aus vorheriger oder nächster Zeile füllendf["age"].ffill(), df["age"].bfill()
Lücken interpolierendf["age"].interpolate()
Marker in fehlende Werte umwandelndf.replace(["n/a", "-", ""], np.nan)
Doppelte Zeilen entfernendf.drop_duplicates()
Letzte Zeile pro Schlüssel behaltendf.drop_duplicates(subset=["city"], keep="last")
Spaltennamen aufräumendf.columns = df.columns.str.strip().str.lower().str.replace(" ", "_")
Extremwerte kappendf["salary"].clip(lower=4000, upper=6000)
Category-Typ für wiederholten Textdf["city"] = df["city"].astype("category")

Textspalten (.str)

In pandas 3 bekommen Textspalten standardmäßig den str dtype. Die .str Methoden arbeiten auf der ganzen Spalte, und fehlende Werte bleiben fehlend.

AufgabeCode
Groß-, Klein- oder Titelschreibungdf["name"].str.upper(), df["name"].str.lower(), df["name"].str.title()
Leerzeichen entfernendf["name"].str.strip()
Text ersetzendf["email"].str.replace("mail.com", "example.com")
Mit Regex ersetzendf["email"].str.replace(r"@.*", "", regex=True)
Enthält, beginnt mitdf["name"].str.contains("a"), df["name"].str.startswith("E")
Länge jedes Wertsdf["name"].str.len()
Erste Zeichendf["name"].str[:2]
In Spalten aufteilendf["email"].str.split("@", expand=True)
Mit Regex-Gruppe extrahierendf["email"].str.extract(r"@(\w+)")
Textspalten verbindendf["name"] + " (" + df["city"] + ")"
Zahlen mit Nullen auffüllendf["salary"].astype("str").str.zfill(6)
Der neue Text-dtypedf["name"].dtype # str

Datum und Uhrzeit

Der .dt Accessor funktioniert auf Datetime-Spalten. Ein sortierter Datumsindex (ts unten) ermöglicht Slicing per Text und Resampling.

AufgabeCode
Spalte in Datetimes umwandelndf["date"] = pd.to_datetime(df["date"])
Mit exaktem Format parsenpd.to_datetime(["03/01/2026", "15/01/2026"], format="%d/%m/%Y")
Jahr, Monat, Wochentagdf["date"].dt.year, df["date"].dt.month, df["date"].dt.day_name()
Datumswerte nach Monat gruppierendf["date"].dt.to_period("M")
Tage zwischen zwei Daten(pd.Timestamp("2026-12-31") - df["date"]).dt.days
Tage oder Monate addierendf["date"] + pd.Timedelta(days=30), df["date"] + pd.DateOffset(months=1)
Zeilen in einem Zeitraumdf[df["date"].between("2021-01-01", "2022-12-31")]
Datumsindex, per Text geslictts = df.set_index("date").sort_index() ts.loc["2021":"2022"]
Summe pro Monatts["salary"].resample("ME").sum()
Wochenmittel; "QE" ist quartalsweise, "YE" jährlichts["salary"].resample("W").mean()
Gleitender Durchschnittts["salary"].rolling(3).mean()
Änderung zur vorherigen Zeilets["salary"].diff(), ts["salary"].pct_change()
Werte eine Zeile nach unten schiebents["salary"].shift(1)
Laufende Summets["salary"].cumsum()
Zeitzonen setzen und umrechnents.index.tz_localize("UTC").tz_convert("Europe/Oslo")

Gruppieren und aggregieren

groupby teilt die Zeilen nach Schlüssel auf, wendet eine Funktion auf jede Gruppe an und fügt die Ergebnisse zusammen.

AufgabeCode
Mittelwert pro Gruppedf.groupby("city")["salary"].mean()
Mehrere Kennzahlen auf einmaldf.groupby("city")["salary"].agg(["mean", "max", "count"])
Benannte Ergebnisspaltendf.groupby("city").agg(avg_pay=("salary", "mean"), people=("name", "count"))
Nach zwei Spalten gruppierendf.groupby(["city", "team"])["salary"].sum()
Schlüssel als Spalten behaltendf.groupby("city", as_index=False)["salary"].mean()
Anzahl Zeilen pro Gruppedf.groupby("city").size()
Gruppenergebnis in jeder Zeiledf["city_avg"] = df.groupby("city")["salary"].transform("mean")
Nur bestimmte Gruppen behaltendf.groupby("city").filter(lambda g: len(g) >= 2)
Zeile mit dem Maximum pro Gruppedf.loc[df.groupby("city")["salary"].idxmax()]
Top n Zeilen pro Gruppedf.sort_values("salary", ascending=False).groupby("city").head(2)
Zeilen in jeder Gruppe nummerierendf.groupby("city").cumcount()
Über die Gruppen iterierenfor city, group in df.groupby("city"): print(city, len(group))
Filtern, gruppieren und sortieren in einer Kette(df.query("age > 30") .groupby("city", as_index=False) .agg(avg_pay=("salary", "mean")) .sort_values("avg_pay", ascending=False))

Pivotieren und umformen

Long-Daten haben eine Zeile pro Beobachtung. Wide-Daten verteilen eine Variable über mehrere Spalten.

AufgabeCode
Pivot-Tabelledf.pivot_table(index="city", columns="team", values="salary", aggfunc="mean", fill_value=0)
Pivot-Tabelle mit Summendf.pivot_table(index="city", values="salary", aggfunc="sum", margins=True)
Kombinationen zählenpd.crosstab(df["city"], df["team"])
Anteile pro Zeilepd.crosstab(df["city"], df["team"], normalize="index")
Wide zu Longlong = df.melt(id_vars="name", value_vars=["age", "salary"], var_name="field", value_name="value")
Long zu Widelong.pivot(index="name", columns="field", values="value")
Innere Indexebene zu Spaltendf.groupby(["city", "team"])["salary"].sum().unstack(fill_value=0)
Eine Zeile pro Listeneintragpd.DataFrame({"id": [1, 2], "tags": [["a", "b"], ["c"]]}).explode("tags")
Spalte One-Hot-kodierenpd.get_dummies(df["team"], prefix="team")
Zeilen und Spalten tauschendf.T

DataFrames kombinieren

concat stapelt Frames, merge verknüpft sie über Schlüsselspalten wie ein SQL-Join.

AufgabeCode
Zeilen stapelnpd.concat([df_2025, df_2026], ignore_index=True)
Nebeneinander stellenpd.concat([left, right], axis=1)
Über eine Schlüsselspalte joinenorders.merge(customers, on="customer_id", how="left")
Join-Typenhow="inner", "left", "right", "outer"
Schlüssel mit unterschiedlichen Namenorders.merge(users, left_on="customer_id", right_on="id")
Join prüfen und Herkunft jeder Zeile markierenorders.merge(customers, on="customer_id", how="left", validate="many_to_one", indicator=True)
Über den Index joinenleft.join(right, how="inner")
Zeilen ohne Treffer in einer anderen Tabelleorders[~orders["customer_id"].isin(customers["customer_id"])]

Plotten mit pandas

pandas zeichnet mit Matplotlib. Jeder Plot-Aufruf gibt eine Matplotlib-ax zurück, die du weiter gestalten kannst.

AufgabeCode
Liniendiagramm einer Seriests["salary"].plot()
Liniendiagramm aus zwei Spaltendf.plot(x="date", y="salary")
Balkendiagramm einer Zusammenfassungdf.groupby("city")["salary"].mean().plot.bar()
Sortierte horizontale Balkendf["city"].value_counts().sort_values().plot.barh()
Histogrammdf["salary"].plot.hist(bins=20)
Streudiagrammdf.plot.scatter(x="age", y="salary")
Boxplot pro Gruppedf.boxplot(column="salary", by="city")
Titel und Achsenbeschriftungax = df.plot(x="date", y="salary", title="Salary") ax.set_ylabel("EUR")
Diagramm anzeigen oder speichernplt.show(), ax.figure.savefig("salary.png", dpi=150)

pandas 3: alte Schreibweisen und was du jetzt schreibst

Code aus älteren Tutorials schlägt in pandas 3 oft fehl oder wirft Warnungen. Schreib stattdessen die Varianten aus der Spalte pandas 3.

Aufgabepandas 3Alte Schreibweise
Funktion auf jede Zelledf.map(f)df.applymap(f)
Aus vorheriger Zeile füllendf.ffill()df.fillna(method="ffill")
Zeilen anhängenpd.concat([df, new_rows])df.append(new_rows)
Resampling zum Monatsendets["salary"].resample("ME").sum()resample("M")
Stündliche Datumswertepd.date_range("2026-01-01", periods=24, freq="h")freq="H"
Einen Wert setzendf.loc[0, "age"] = 37df["age"][0] = 37
Gefilterte Teilmenge ändernhigh = df[df["salary"] > 5000] high["salary"] = 0high = df[df["salary"] > 5000].copy()
Ist das eine Textspalte?df["name"].dtype == "str"df["name"].dtype == object

Der pandas-Code, den Datenanalysten jeden Tag brauchen, sortiert nach Aufgabe: Daten erstellen und laden, untersuchen, Zeilen auswählen und filtern, Spalten hinzufügen, fehlende Werte bereinigen, mit Text und Datumswerten arbeiten, gruppieren und aggregieren, umformen, zusammenführen und plotten. Jede Zeile ist ein kurzes Snippet zum Einfügen, plus eine Zeile dazu, was es tut.

Alles hier ist für pandas 3 geschrieben, die Version, die Coddy verwendet: Textspalten nutzen den neuen str dtype, Copy-on-Write ist immer aktiv, und entfernte APIs wie applymap und fillna(method=...) stehen nur in der Tabelle mit alten Schreibweisen. Die Beispiele verwenden einen DataFrame df mit den Spalten name, city, team, age, salary, date und email. Neu in Python? Starte mit dem Python Spickzettel und dem Python Playground, und halte die Spickzettel zu NumPy, Matplotlib und scikit-learn neben diesem bereit.

FAQ zum pandas Spickzettel

Ist dieser pandas Spickzettel kostenlos?
Ja. Dieser pandas Spickzettel ist komplett kostenlos, ganz ohne Anmeldung. Setz ein Lesezeichen oder druck ihn im Browser als PDF, und schau wieder vorbei, wenn du den genauen Aufruf für ein groupby, ein merge oder eine Pivot-Tabelle brauchst.
Welche pandas-Version deckt dieser Spickzettel ab?
pandas 3. Textspalten nutzen den neuen str dtype, Copy-on-Write ist immer aktiv, und in pandas 3 entfernte Aufrufe (applymap, fillna(method=...), append, die Frequenz-Aliase M und H) stehen nur in der letzten Tabelle, neben dem, was du stattdessen schreibst. Fast jedes Snippet läuft auch mit pandas 2.2, außer den Zeilen, die auf den str dtype oder auf Copy-on-Write angewiesen sind.
Was ist der Unterschied zwischen loc und iloc?
loc wählt nach Label aus: Indexwerte und Spaltennamen, und ein Slice wie df.loc[0:2] schließt sein Ende ein. iloc wählt nach ganzzahliger Position aus, wie bei einer Python-Liste, also gibt df.iloc[0:2] die ersten zwei Zeilen zurück und schließt das Ende aus. Nutze loc mit einer Bedingung, um Zeilen zu filtern und Spalten in einem Schritt auszuwählen: df.loc[df["age"] > 30, ["name"]].
Wie filtere ich einen DataFrame nach mehreren Bedingungen?
Setz jede Bedingung in Klammern und verknüpfe sie mit & für und, | für oder und ~ für nicht: df[(df["age"] > 30) & (df["city"] == "Oslo")]. Pythons and und or funktionieren nicht auf ganzen Spalten. Bei langen Filtern ist df.query("age > 30 and city == 'Oslo'") leichter zu lesen.
Was ist der Unterschied zwischen merge, join und concat?
merge kombiniert zwei DataFrames über Schlüsselspalten, wie ein SQL-Join, mit how="inner", "left", "right" oder "outer". join ist eine Abkürzung, die über den Index mergt. concat gleicht überhaupt keine Schlüssel ab: Es stapelt Frames übereinander oder mit axis=1 nebeneinander.
Warum ändert meine Zuweisung den DataFrame nicht?
Seit pandas 3 sorgt Copy-on-Write dafür, dass sich jede Auswahl wie eine Kopie verhält. Verkettete Zuweisungen wie df["age"][0] = 37 ändern ein temporäres Objekt und lassen df unverändert. Schreib es stattdessen als einen loc Aufruf: df.loc[0, "age"] = 37. Methoden wie dropna und fillna geben ebenfalls ein neues Objekt zurück, also weise das Ergebnis zu.
Kann ich pandas-Code online ausführen?
Ja. Der kostenlose Matplotlib Playground führt Python mit pandas, NumPy, Matplotlib und scikit-learn in deinem Browser aus, also kannst du jedes Snippet aus diesem Spickzettel einfügen und ohne Installation ausführen. Der Machine-Learning-Kurs von Coddy bringt dir pandas Schritt für Schritt bei, von deinem ersten DataFrame bis zu den Daten, mit denen du ein Modell fütterst.
Illustration der Programmiersprachen bei Coddy

Lerne Pandas mit Coddy

LOS GEHT'S