Tipps & Tricks

Effiziente Bereinigung von CSV-Dateien mit Python: Ein Leitfaden für Einsteiger

10 min Lesezeit
Effiziente Bereinigung von CSV-Dateien mit Python: Ein Leitfaden für Einsteiger

Einführung

Die Bereinigung von Datensätzen ist eine der grundlegenden Fähigkeiten, die man beim Einstieg in die Datenanalyse erlernt. Obwohl es einfach erscheinen mag, ist es eine der wichtigsten Fertigkeiten, die immer wieder benötigt wird.

Interessanterweise verbringen selbst erfahrene Fachleute einen Großteil ihrer Zeit mit der Datenbereinigung, anstatt Analysen durchzuführen, Modelle zu erstellen oder Ergebnisse zu bewerten. Der Grund dafür ist, dass Rohdaten selten sauber sind. Sie können fehlende Werte, falsche Formate, doppelte Zeilen, unordentliche Texte, ungültige Daten, merkwürdige Kategorien und fehlerhafte Einträge enthalten.

Bevor man die Informationen im Datensatz verstehen kann, müssen diese Probleme behoben werden.

In diesem Leitfaden werden wir eine unordentliche CSV-Datei mit Kundendaten mithilfe von Python und der Bibliothek pandas bereinigen. Wir beginnen mit dem Laden und Überprüfen der Daten, gefolgt von der Bereinigung der Spaltennamen, dem Umgang mit fehlenden Werten, dem Entfernen von Duplikaten, der Standardisierung von Texten, der Umwandlung von Datentypen, der Validierung von E-Mails und dem Speichern der endgültigen bereinigten CSV-Datei.

1. Laden der CSV-Datei

Der erste Schritt besteht darin, den unordentlichen Datensatz in pandas zu laden.

import pandas as pd

df = pd.read_csv("messy_customers.csv", keep_default_na=False)
df

Wir verwenden eine CSV-Datei mit Kundendaten, die häufige Probleme mit der Datenqualität aufweist. Wie bereits zu sehen ist, enthält die Datei unordentliche Spaltennamen, inkonsistente Textformatierungen, gemischte Datumsformate, fehlende Werte, doppelte Zeilen und Zahlen, die als Text gespeichert sind. Wie die Struktur von Datensätzen den Programmierstil beeinflusst

2. Überprüfung vor der Bereinigung

Bevor wir mit der Bereinigung beginnen, müssen wir verstehen, was sich tatsächlich im Datensatz befindet.

print("Shape:", df.shape)
print("\nSpaltennamen:")
print(df.columns.tolist())
print("\nDatentypen:")
print(df.dtypes)
print("\nExakte doppelte Zeilen:", df.duplicated().sum())

Dies gibt uns einen schnellen Überblick über den Datensatz, bevor wir Änderungen vornehmen.

Wir sehen, dass der Datensatz 10 Zeilen und 8 Spalten hat. Die Spaltennamen sind unordentlich, da einige von ihnen zusätzliche Leerzeichen und inkonsistente Groß- und Kleinschreibung aufweisen. Außerdem sehen wir, dass jede Spalte als Objekt gespeichert ist, was normalerweise bedeutet, dass pandas sie als Text behandelt.

Die Überprüfung auf Duplikate zeigt auch, dass es 1 exakte doppelte Zeile gibt. Dies ist nützlich, um frühzeitig zu wissen, da doppelte Datensätze die endgültige Analyse beeinflussen können.

3. Bereinigung der Spaltennamen

Da wir nun wissen, dass die Spaltennamen unordentlich sind, werden wir sie zuerst bereinigen.

df.columns = (
 df.columns
 .str.strip()
 .str.lower()
 .str.replace(r"\s+", "_", regex=True)
)
df.columns.tolist()

Dieser Schritt entfernt zusätzliche Leerzeichen aus den Spaltennamen, konvertiert alles in Kleinbuchstaben und ersetzt Leerzeichen durch Unterstriche.

Jetzt sind die Spaltennamen viel einfacher zu handhaben. Anstatt Namen mit Leerzeichen wie Email Address zu verwenden, können wir einfach email_address nutzen. Dies macht den Code übersichtlicher und hilft, kleine Fehler später zu vermeiden.

4. Ersetzen von Leerzeichen und Platzhaltern

Als Nächstes ersetzen wir leere Werte und gängige Platzhalter durch ordnungsgemäße fehlende Werte.

df = df.replace(r"^\s*$", pd.NA, regex=True)
df = df.replace(
 ["N/A", "n/a", "NA", "unknown", "not a date"],
 pd.NA,
)
df.isna().sum()

In der realen Welt zeigen CSV-Dateien häufig fehlende Daten auf unterschiedliche Weise. Einige Zellen sind leer, andere verwenden N/A oder Werte wie unknown oder not a date.

Wir wandeln all diese in ordnungsgemäße fehlende Werte um, damit pandas sie korrekt erkennen kann. Nach diesem Schritt wird es einfacher, fehlende Werte später zu zählen, zu füllen oder zu entfernen.

5. Entfernen von doppelten Zeilen

Jetzt werden wir exakte doppelte Zeilen aus dem Datensatz entfernen.

print("Zeilen vor der Bereinigung:", len(df))
df = df.drop_duplicates().copy()
print("Zeilen nach der Bereinigung:", len(df))

Doppelte Zeilen können Probleme in Ihrer Analyse verursachen, da derselbe Datensatz mehr als einmal gezählt werden kann.

Hier hatten wir 10 Zeilen vor dem Entfernen von Duplikaten und 9 Zeilen danach. Das bedeutet, dass eine exakte doppelte Zeile aus dem Datensatz entfernt wurde.

6. Bereinigung der Textspalten

Nun werden wir die textbasierten Spalten bereinigen, damit die Werte konsistenter sind.

text_columns = ["customer_id", "full_name", "email_address", "city", "membership"]
for column in text_columns:
 df[column] = df[column].astype("string").str.strip()
df["full_name"] = (
 df["full_name"]
 .str.replace(r"\s+", " ", regex=True)
 .str.title()
)
df["city"] = df["city"].str.title()
df["membership"] = df["membership"].str.lower()
df["email_address"] = df["email_address"].str.lower()
df[text_columns]

Textspalten benötigen in der Regel eine zusätzliche Bereinigung, da Menschen dieselben Informationen auf unterschiedliche Weise eingeben.

In diesem Schritt entfernen wir zusätzliche Leerzeichen aus customer_id, full_name, email_address, city und membership. Dann bereinigen wir die Formatierung, sodass Namen und Städte in der Titel-Schreibweise und E-Mails sowie Mitgliedschaftswerte in Kleinbuchstaben dargestellt werden.

Dies erleichtert das Lesen des Datensatzes und hilft, Kategorienprobleme später zu vermeiden. Beispielsweise sollten Gold, GOLD und gold alle als derselbe Mitgliedschaftswert behandelt werden.

7. Standardisierung von Kategorien

Nun werden wir die Mitgliedschaftsspalte bereinigen, sodass sie nur gültige Kategorien enthält.

allowed_memberships = {"bronze", "silver", "gold"}
df.loc[~df["membership"].isin(allowed_memberships), "membership"] = pd.NA
df["membership"].value_counts(dropna=False)

Dieser Schritt stellt sicher, dass die Mitgliedschaftsspalte nur die Werte enthält, die wir erwarten.

In diesem Datensatz sind die gültigen Mitgliedschaftstypen bronze, silver und gold. Jeder Wert außerhalb dieser Kategorien, wie platinum, wird durch einen fehlenden Wert ersetzt, damit wir ihn später bearbeiten können.

8. Umwandlung des Alters in eine Zahl

Als Nächstes wandeln wir die Altersangabe von Text in Zahlen um.

df["age"] = pd.to_numeric(df["age"], errors="coerce")
df.loc[~df["age"].between(0, 120), "age"] = pd.NA
df["age"] = df["age"].astype("Int64")
df[["full_name", "age"]]

Die Altersangabe war als Text gespeichert, daher müssen wir sie in eine numerische Spalte umwandeln, bevor wir sie für Analysen verwenden.

Wir entfernen auch Werte, die keinen Sinn ergeben, wie negative Altersangaben oder Altersangaben über 120. Jedes ungültige Alter wird in einen fehlenden Wert umgewandelt, den wir später beheben werden.

9. Umwandlung gemischter Datumsformate

Jetzt werden wir die join_date-Spalte bereinigen.

df["join_date"] = pd.to_datetime(
 df["join_date"],
 format="mixed",
 dayfirst=True,
 errors="coerce",
)
df[["full_name", "join_date"]]

Datumsangaben sind in CSV-Dateien oft unordentlich, da sie in unterschiedlichen Formaten erscheinen können.

Dieser Schritt wandelt die join_date-Spalte in eine ordentliche Datetime-Spalte um. Wir verwenden „mixed“, da die Daten in dieser Datei nicht alle dasselbe Format haben. Jedes ungültige Datum wird in einen fehlenden Wert umgewandelt.

10. Bereinigung von Währungswerten

Als Nächstes bereinigen wir die total_spend-Spalte.

df["total_spend"] = (
 df["total_spend"]
 .astype("string")
 .str.replace(r"[^0-9.-]", "", regex=True)
)
df["total_spend"] = pd.to_numeric(df["total_spend"], errors="coerce")
df[["full_name", "total_spend"]]

Die total_spend-Spalte enthält Währungssymbole, Kommas und Textwerte, sodass pandas sie noch nicht als Zahl behandeln kann.

Dieser Schritt entfernt alles außer Zahlen, Dezimalpunkten und Minuszeichen. Anschließend wandeln wir die Spalte in einen numerischen Wert um, damit wir Summen, Durchschnitte und andere nützliche Kennzahlen berechnen können.

11. Validierung von E-Mail-Adressen

Jetzt überprüfen wir, ob die E-Mail-Adressen ein gültiges Format haben.

email_pattern = r"^[^\s@]+@[^\s@]+\.[^\s@]+$"
valid_email = df["email_address"].str.match(email_pattern, na=False)
df.loc[~valid_email, "email_address"] = pd.NA
df[["full_name", "email_address"]]

Dies ist ein einfacher Validierungsschritt für E-Mails.

Es wird überprüft, ob jede E-Mail die grundlegende Struktur einer E-Mail-Adresse hat. Wenn eine E-Mail offensichtlich ungültig ist, ersetzen wir sie durch einen fehlenden Wert. Dies hilft, die email_address-Spalte sauberer und zuverlässiger zu halten.

12. Umgang mit fehlenden Werten

Jetzt entscheiden wir, was mit den verbleibenden fehlenden Werten geschehen soll.

df = df.dropna(subset=["customer_id"]).copy()
df["full_name"] = df["full_name"].fillna("Unknown")
df["city"] = df["city"].fillna("Unknown")
df["membership"] = df["membership"].fillna("unassigned")
median_age = int(df["age"].median())
df["age"] = df["age"].fillna(median_age)
df["total_spend"] = df["total_spend"].fillna(0.0)
print("Medianalter verwendet:", median_age)
df.isna().sum()

Für diesen Datensatz entfernen wir Zeilen, in denen customer_id fehlt, da dies der Hauptidentifikator für jeden Kunden ist.

Für die anderen Spalten verwenden wir sinnvolle Ersetzungen. Fehlende Namen und Städte werden zu Unknown, fehlende Mitgliedschaftswerte werden zu unassigned, fehlende Altersangaben werden mit dem Medianalter gefüllt, und fehlende Ausgabenwerte werden mit 0.0 gefüllt.

Wir haben immer noch fehlende Werte in email_address und join_date, und das ist in Ordnung. Manchmal ist es besser, fehlende Werte zu belassen, anstatt einen Wert zu erzwingen, der möglicherweise nicht korrekt ist.

13. Überprüfung der bereinigten Daten

Bevor wir die endgültige Datei speichern, sollten wir überprüfen, ob der bereinigte Datensatz den erwarteten Regeln entspricht.

final_memberships = {"bronze", "silver", "gold", "unassigned"}
assert df["customer_id"].notna().all()
assert df["customer_id"].is_unique
assert df["age"].between(0, 120).all()
assert df["total_spend"].ge(0).all()
assert df["membership"].isin(final_memberships).all()
print("Alle Validierungsprüfungen bestanden.")

Diese Überprüfungen helfen uns zu bestätigen, dass die wichtigen Bereinigungsschritte funktioniert haben.

Wir überprüfen, dass jeder Kunde eine ID hat, die Kunden-IDs eindeutig sind, die Altersangaben gültig sind, die Gesamtausgaben nicht negativ sind und die Mitgliedschaftswerte nur aus der endgültigen genehmigten Liste stammen. Wenn alle Prüfungen bestanden sind, können wir uns sicherer fühlen, diesen bereinigten Datensatz zu verwenden.

14. Überprüfung des Endergebnisses

Jetzt können wir den bereinigten Datensatz überprüfen und sicherstellen, dass alles korrekt aussieht.

df.head()

In diesem Stadium ist die Datenqualität deutlich besser als zuvor.

Die Spaltennamen sind konsistent, die Textwerte wurden bereinigt, die Altersangabe ist nun numerisch, das Beitrittsdatum hat ein korrektes Datumsformat, und die Gesamtausgaben sind bereit für Berechnungen.

Diese letzte Überprüfung ist wichtig, da sie uns die letzte Chance gibt, offensichtliche Probleme schnell zu erkennen, bevor wir die bereinigte Datei speichern.

15. Speichern der bereinigten CSV-Datei

Schließlich speichern wir den bereinigten Datensatz als neue CSV-Datei.

df.to_csv(
 "clean_customers.csv",
 index=False,
 date_format="%Y-%m-%d",
)
print("Bereinigte Datei gespeichert unter clean_customers.csv")

Wir speichern den bereinigten Datensatz als separate Datei, damit die ursprüngliche unordentliche CSV-Datei unverändert bleibt.

Dies ist eine gute Praxis, da Sie immer auf die Rohdatei zurückgreifen können, falls etwas schiefgeht oder wenn Sie später einen anderen Bereinigungsansatz anwenden möchten.

Fazit

Die meisten Menschen glauben, sie wüssten, wie man einen Datensatz bereinigt, aber die eigentliche Herausforderung beginnt, wenn man sicherstellen muss, dass die Daten tatsächlich bereit für die Analyse sind.

Es geht nicht nur darum, fehlende Werte zu entfernen oder Spaltennamen zu korrigieren. Man muss auch die Datentypen überprüfen, ungültige Werte behandeln, Duplikate entfernen, Kategorien standardisieren, wichtige Felder validieren und abschließende Prüfungen durchführen, bevor man dem Datensatz vertraut.

Hier machen viele Anfänger Fehler. Sie bereinigen die Daten oberflächlich, überprüfen jedoch nicht, ob der endgültige Datensatz sinnvoll ist.

In diesem Leitfaden haben wir einen einfachen, aber praktischen Workflow zur Bereinigung einer unordentlichen CSV-Datei mit Python und pandas verfolgt. Wir haben die Daten geladen, überprüft, die Spalten bereinigt, fehlende Werte behandelt, Texte bereinigt, Zahlen und Daten umgewandelt, E-Mails validiert, das Endergebnis überprüft und eine bereinigte CSV-Datei gespeichert. Der umfassende Leitfaden für Einsteiger in die Datenwissenschaft 2026: Wichtige Skills und Fallstricke 5 Powerful Python Decorators for High-Performance Data Pipelines

Dies ist der Workflow, den Sie in nahezu jedem realen Datenprojekt wiederverwenden können. Der Datensatz kann sich ändern, aber der Prozess bleibt größtenteils gleich: Überprüfen, Bereinigen, Validieren und Speichern.

„`


Quellen: kdnuggets

Bildquelle: KI generiert

KI Snack