Eine CSV einlesen und prüfen, was angekommen ist
Eine Datei mit read_csv einlesen und sofort mit shape, head, info und describe prüfen — denn eine fehlerhaft eingelesene Datei liefert falsche Antworten, ohne jemals einen Fehler auszulösen.
Wie möchtest du lernen?
Das Problem, das wir lösen
Bisher wurde jeder Wert in der Tabelle von Hand in den Code eingegeben. Bei drei Zeilen funktioniert das.
Echte Daten leben nicht im Code. Sie leben in einer Datei — von jemandem per E-Mail geschickt, aus einem System exportiert oder aus einer Tabellenkalkulation gespeichert. Und die Datei hat zwölftausend Zeilen, nicht zwölf.
Diese Datei sieht meistens so aus: reiner Text, die Spaltennamen in der ersten Zeile, dann eine Zeile pro Datensatz, getrennt durch Kommas:
product,quantity,price
pen,12,15.0
notebook,5,60.0Das ist eine CSV — comma-separated values. Sie in eine Tabelle zu verwandeln, erfordert eine einzige Zeile in pandas, und es ist die meistgenutzte Zeile in ganz pandas.
Aber es gibt eine Gewohnheit, die du dir direkt nach dieser Zeile aneignen solltest, und das ist das eigentliche Thema dieses Kapitels: Sobald eine Datei eingelesen ist, schau sie dir an. Wie viele Zeilen angekommen sind, ob die Spaltennamen deinen Erwartungen entsprechen, ob die numerischen Spalten wirklich als Zahlen eingelesen wurden. Überspringst du diese dreißig Sekunden, taucht der Fehler viel später auf — wenn ein Ergebnis falsch ist und kein einziger Fehler ausgelöst wurde.
Am Ende dieses Kapitels kannst du
- Eine Datei mit
pd.read_csv()einlesen und das darauf folgende Pfadproblem lösen - Eine Datei schnell mit
head(),tail(),shapeundcolumnsüberprüfen info()lesen, um Zeilenanzahl, leere Zellen und den Typ jeder Spalte auf einmal zu sehen- Die numerischen Spalten mit
describe()zusammenfassen - Einen
FileNotFoundErrorsowie ein falsches Trennzeichen erkennen und beheben
Voraussetzungen: Series und DataFrame — die zwei Dinge in pandas.
Erstelle zuerst die Datei
Erstelle in deinem Projektordner eine Datei namens sales.csv mit genau diesen sechs Zeilen:
product,quantity,price
pen,12,15.0
notebook,5,60.0
bag,2,850.0
bottle,7,120.0
eraser,30,8.0Die erste Zeile enthält keine Daten, sondern die Spaltennamen — den Header. Die anderen fünf Zeilen sind fünf Datenzeilen.
Das Einlesen in einer Zeile
import pandas as pd
sales = pd.read_csv("sales.csv")
print(sales)product quantity price
0 pen 12 15.0
1 notebook 5 60.0
2 bag 2 850.0
3 bottle 7 120.0
4 eraser 30 8.0Diese eine Zeile hat drei Dinge getan, und alle drei im Stillen:
Erstens hat sie die erste Zeile als Header genommen — sodass product, quantity und price zu Spaltennamen wurden und nicht zu einer Datenzeile.
Zweitens hat sie einen Index erstellt, die 0 bis 4 am linken Rand. Das stand nicht in der Datei.
Drittens, und das ist der entscheidende Punkt: Sie hat den Typ jeder Spalte erraten. Alles in der Datei ist Text — 12 sind in Wirklichkeit zwei Zeichen. Pandas hat sich jede Spalte angesehen und entschieden, ob es sich um Zahlen oder Text handelt.
Diese Schätzung liegt meistens richtig. Aber wenn sie falsch ist, tritt kein Fehler auf — und genau deshalb schaust du hin.
Die vier Dinge, die nach dem Einlesen einer Datei zu prüfen sind
shape — wie viel angekommen ist
print(sales.shape)(5, 3)Fünf Zeilen, drei Spalten. Die Datei hatte sechs Zeilen und diese Tabelle hat fünf Zeilen, weil der Header keine Datenzeile ist. Wenn die Zahl weit unter dem liegt, was du erwartet hast, oder genau um eins zu hoch ist, ist das das erste Anzeichen dafür, dass etwas falsch eingelesen wurde.
head() und tail() — der Anfang und das Ende
print(sales.head(3))product quantity price
0 pen 12 15.0
1 notebook 5 60.0
2 bag 2 850.0Alle zwölftausend Zeilen einer echten Datei auszugeben, überflutet das Terminal und verrät dir gar nichts. head() zeigt die ersten paar Zeilen — fünf, wenn du nichts anderes angibst. tail() macht dasselbe am Ende, und ein Blick ans Ende ist besonders nützlich, da exportierte Dateien dort unten oft eine verirrte Leerzeile oder eine Summenzeile enthalten.
info() — alles auf einen Blick
sales.info()<class 'pandas.core.frame.DataFrame'>
RangeIndex: 5 entries, 0 to 4
Data columns (total 3 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 product 5 non-null object
1 quantity 5 non-null int64
2 price 5 non-null float64
dtypes: float64(1), int64(1), object(1)
memory usage: 252.0+ bytesBeachte, dass hier sales.info() steht und nicht print(sales.info()) — diese Methode gibt ihre Ausgabe selbst aus und liefert nichts zurück. Wenn du sie in ein print packst, hängt das am Ende ein überflüssiges None an.
Das ist der nützlichste Befehl, den du nach dem Einlesen einer Datei ausführen kannst, da er zwei wichtige Fakten auf einmal liefert:
Non-Null Count — wie viele Zellen in jeder Spalte tatsächlich gefüllt sind. Alle drei Spalten zeigen hier 5 non-null, es ist also nichts leer. Ein 4 non-null an irgendeiner Stelle bedeutet, dass eine Zelle in dieser Spalte leer ist — und das wird deine Rechenergebnisse verändern.
Dtype — worauf die Schätzung hinausgelaufen ist. quantity wurde als int64 eingelesen, price als float64, product als object. Genau das wollten wir.
(Die Zahl bei memory usage in der letzten Zeile kann sich auf deinem Rechner unterscheiden und spielt keine Rolle.)
describe() — eine Zusammenfassung der numerischen Spalten
print(sales.describe())quantity price
count 5.00000 5.000000
mean 11.20000 210.600000
std 11.12205 360.217712
min 2.00000 8.000000
25% 5.00000 15.000000
50% 7.00000 60.000000
75% 12.00000 120.000000
max 30.00000 850.000000Es wählt die numerischen Spalten aus und führt für jede davon acht Berechnungen durch. product fehlt, weil es Text ist.
Eine Sache sollte dir hier sofort ins Auge fallen: Der Mittelwert (mean) von price liegt bei 210.6, während die 50% — der Median — nur bei 60 liegen. Ein so großer Abstand bedeutet, dass ein einzelner Wert weit über den restlichen liegt, und max nennt ihn beim Namen: 850. Genau so liest man describe() — wenn Mittelwert und Median auseinanderdriften, schau dort genauer hin.
Ein vollständiges Beispiel
report.py:
import pandas as pd
sales = pd.read_csv("sales.csv")
print("Rows, columns:", sales.shape)
print()
print(sales.head(3))
print()
print("Columns :", list(sales.columns))
print("Total qty :", sales["quantity"].sum())
print("Avg price :", round(sales["price"].mean(), 2))Rows, columns: (5, 3)
product quantity price
0 pen 12 15.0
1 notebook 5 60.0
2 bag 2 850.0
Columns : ['product', 'quantity', 'price']
Total qty : 56
Avg price : 210.6Ein kleines Programm, aber sein Aufbau ist beachtenswert — einlesen, dann überprüfen, dann rechnen. shape und head() sind keine Berechnungen, sie sind Fragen: Habe ich die richtige Datei eingelesen? Sind es so viele Zeilen, wie es sein sollten?
Und es gibt einen Grund, list(sales.columns) auszugeben. Als Liste wird jeder Name in Anführungszeichen zurückgegeben, sodass ein Name wie 'quantity ' mit einem nachfolgenden Leerzeichen sofort auffällt. Auf jede andere Weise ausgegeben bleibt dieses Leerzeichen unsichtbar und rächt sich später als KeyError.
Wenn etwas schiefgeht
FileNotFoundError: [Errno 2] No such file or directory: 'sales.csv' Python sucht im aktuellen Ordner und hat die Datei dort nicht gefunden. Das ist dasselbe Problem wie in Kapitel zwei des Python-Kurses: Das Terminal befindet sich an einem Ort und die Datei an einem anderen. Führe pwd aus, um zu sehen, wo du bist, dir, um zu sehen, ob die Datei da ist, und wechsle dann mit cd. Unter Windows heißt die Datei vielleicht in Wahrheit sales.csv.txt — aktiviere im Explorer die Anzeige von Dateiendungen.
Die gesamte Datei ist als eine einzige Spalte angekommen Das Trennzeichen ist kein Komma. Dateien, die in weiten Teilen Europas gespeichert werden, verwenden ein Semikolon, da das Komma dort das Dezimaltrennzeichen ist. Schreibe pd.read_csv("sales.csv", sep=";"). Für tabulatorgetrennte Dateien verwende sep="\t".
Eine numerische Spalte wurde als object eingelesen Irgendwo hat sich Text in die Spalte eingeschlichen — ein N/A, ein -, eine leere Zelle oder ein Tausender-Komma (1,200). Führe df["col"].unique() aus, um zu sehen, was tatsächlich darin steht; der Ausreißer fällt meistens sofort auf. Die Reparatur lautet pd.to_numeric(df["col"], errors="coerce"), was alles Nicht-Numerische in einen leeren Wert umwandelt — ausführlich behandelt im Kapitel über fehlende Daten.
UnicodeDecodeError Die Datei ist nicht als UTF-8 gespeichert, was bei Dateien aus einer Tabellenkalkulation regelmäßig vorkommt. Versuche pd.read_csv("sales.csv", encoding="utf-8-sig"), und falls das fehlschlägt, encoding="latin-1".
Die erste Datenzeile wurde zu den Spaltennamen, obwohl die Datei keinen Header hatte Schreibe pd.read_csv("sales.csv", header=None), und die Spalten heißen 0, 1, 2. Um ihnen Namen zu geben, füge names=["product", "quantity", "price"] hinzu.
Ein überflüssiges None wird nach sales.info() ausgegeben Es wurde als print(sales.info()) geschrieben. info() gibt seine Ausgabe selbst aus und liefert nichts zurück, sodass print das zurückgegebene None ausgibt. Schreibe einfach nur sales.info().
Schritt 4 von 6 — Vorhersagen
Prüfe dein Verständnis
Die Datei hat sechs Zeilen. Was gibt shape aus?
from io import StringIO
import pandas as pd
# Stands in for sales.csv, so this snippet runs on its own.
RAW = """product,quantity,price
pen,12,15.0
notebook,5,60.0
bag,2,850.0
bottle,7,120.0
eraser,30,8.0
"""
sales = pd.read_csv(StringIO(RAW))
print(sales.shape)- A(5, 3)
- B(5, 4)
- C(3, 5)
- D(6, 3)
Was verrät dir die Spalte Non-Null Count von info()?
- AWie viele Zellen in jeder Spalte tatsächlich gefüllt sind — eine Zahl unterhalb der Zeilenanzahl bedeutet, dass dort leere Zellen vorhanden sind
- BWie viele Zellen in jeder Spalte leer sind
- CWie viel Speicherplatz jede Spalte belegt
- DWie viele verschiedene Werte jede Spalte hat
Die Datei ist durch Semikolons getrennt, aber es wurde kein sep angegeben. Was wird ausgegeben?
from io import StringIO
import pandas as pd
# Stands in for sales.csv, so this snippet runs on its own.
RAW = """product;quantity
pen;12
notebook;5
"""
df = pd.read_csv(StringIO(RAW))
print(df.shape)
print(list(df.columns))- A(3, 1) ['product;quantity']
- B(2, 1) ['product;quantity']
- C(2, 2) ['product', 'quantity']
- DEin `ParserError`
Zum Antworten brauchst du ein Konto
Melde dich an, um deine Antworten zu prüfen
Die Fragen stehen oben, und sie im Kopf durchzuarbeiten ist der wichtige Teil. Melde dich an, um die Antworten, die Erklärungen und die dreistufigen Hinweise zu sehen.
Jetzt bist du dran
Erstelle eine Datei namens students.csv mit mindestens acht Personen in drei Spalten — Name, Alter und Note.
Schreibe dann ein Skript report.py, das:
- Die Datei einliest
shapeundlist(columns)ausgibthead(3)undtail(2)ausgibtinfo()ausführt und feststellt, ob alle drei Spaltentypen deinen Erwartungen entsprechendescribe()ausgibt sowie separat den Mittelwert und das Maximum der Notenspalte
Bringe das Programm danach mit Absicht zum Scheitern — dreimal, und beobachte jedes Mal genau, was passiert:
- Setze
N/Ain eine Zelle der Notenspalte. Was zeigtDtypeininfo()jetzt an? Was ist mit dem Mittelwert passiert? - Ersetze jedes Komma in der Datei durch ein Semikolon. Was zeigt
shapejetzt an und warum? - Lösche die erste Zeile, den Header. Wie viele Zeilen sind angekommen, und wie lauten jetzt die Spaltennamen?
Alle drei Fälle treten im Arbeitsalltag ständig auf, und jeder zeigt ein klares Symptom. Sie heute gezielt herbeizuführen bedeutet, sie beim nächsten Mal auf den ersten Blick zu erkennen.
Schritt 6 von 6
Herausforderung — das Kapitel-Quiz
Zehn Fragen von leicht bis schwer. Die letzten sind absichtlich knifflig.
Melde dich an, um das Quiz zu machen