Als ich anfing, Pandas zu verwenden, dachte ich, dass ich ziemlich intestine damit zurechtkomme.
Ich könnte Datensätze bereinigen und ausführen groupbyTabellen zusammenführen und schnelle Analysen in einem Jupyter-Pocket book erstellen. In den meisten Tutorials fühlte es sich unkompliziert an: Daten laden, transformieren, visualisieren, fertig.
Und um honest zu sein, normalerweise mein Code hat funktioniert.
Bis das nicht der Fall warfare.
Irgendwann stieß ich auf seltsame Probleme, die schwer zu erklären waren. Die Zahlen summierten sich nicht so, wie ich es erwartet hatte. Eine Spalte, die numerisch aussah, verhielt sich wie Textual content. Manchmal verlief eine Transformation fehlerfrei, lieferte aber eindeutig falsche Ergebnisse.
Das Frustrierende daran warfare, dass Pandas sich selten beschwerten.
Es gab keine offensichtlichen Ausnahmen oder Abstürze. Der Code wurde einwandfrei ausgeführt – er lieferte lediglich falsche Ergebnisse.
Da wurde mir etwas Wichtiges klar: Die meisten Pandas-Tutorials konzentrieren sich darauf was du tun kannstaber sie erklären selten wie sich Pandas tatsächlich unter der Haube verhält.
Dinge wie:
- Wie Pandas damit umgehen Datentypen
- Wie Indexausrichtung funktioniert
- Der Unterschied zwischen a Kopie und eine Ansicht
- und wie man schreibt defensiver Datenmanipulationscode
Diese Konzepte sind nicht besonders spannend, wenn Sie Pandas zum ersten Mal lernen. Sie sind nicht so auffällig wie groupby Tips oder ausgefallene Visualisierungen.
Aber es sind genau die Dinge, die verhindern stille Fehler in realen Datenpipelines.
In diesem Artikel werde ich vier Pandas-Konzepte durchgehen, die in den meisten Tutorials übersprungen werden – dieselben, die in meinem eigenen Code immer wieder subtile Fehler verursacht haben.
Wenn Sie diese Ideen verstehen, werden Ihre Pandas-Workflows viel zuverlässiger, insbesondere wenn Ihre Analyse beginnt, sich zu entwickeln Produktionsdatenpipelines statt einmaliger Notebooks.
Beginnen wir mit einer der häufigsten Problemquellen: Datentypen.
Ein kleiner Datensatz (und ein subtiler Fehler)
Um diese Ideen zu konkretisieren, arbeiten wir mit einem kleinen E-Commerce-Datensatz.
Stellen Sie sich vor, wir analysieren Bestellungen aus einem On-line-Store. Jede Zeile stellt eine Bestellung dar und enthält Umsatz- und Rabattinformationen.
import pandas as pd
orders = pd.DataFrame({
"order_id": (1001, 1002, 1003, 1004),
"customer_id": (1, 2, 2, 3),
"income": ("120", "250", "80", "300"), # appears to be like numeric
"low cost": (None, 10, None, 20)
})
orders
Ausgabe:

Auf den ersten Blick sieht alles regular aus. Wir haben Umsatzwerte, einige Rabatte und einige fehlende Einträge.
Beantworten wir nun eine einfache Frage:
Wie hoch ist der Gesamtumsatz?
orders("income").sum()
Sie könnten etwas erwarten wie:
750
Stattdessen gibt Pandas Folgendes zurück:
'12025080300'
Dies ist ein perfektes Beispiel für das, was ich zuvor erwähnt habe: Pandas scheitern oft stillschweigend. Der Code wird erfolgreich ausgeführt, aber die Ausgabe entspricht nicht Ihren Erwartungen.
Der Grund ist subtil, aber unglaublich wichtig:
Der income Spalte scheint numerisch zu sein, aber Pandas speichert sie tatsächlich als Textual content.
Wir können dies bestätigen, indem wir die Datentypen des Datenrahmens überprüfen.
orders.dtypes
Dieses kleine Element stellt eine der häufigsten Fehlerquellen in Pandas-Workflows vor: Datentypen.
Lassen Sie uns das als nächstes beheben.
1. Datentypen: Die verborgene Quelle vieler Pandas-Bugs
Das Downside, das wir gerade gesehen haben, lässt sich auf etwas Einfaches zurückführen: Datentypen.
Auch wenn die income Spalte sieht numerisch aus, Pandas hat sie als interpretiert Objekt (im Wesentlichen Textual content).
Das können wir bestätigen:
orders.dtypes
Ausgabe:
order_id int64
customer_id int64
income object
low cost float64
dtype: object
Weil income als Textual content gespeichert wird, verhalten sich Vorgänge anders. Als wir Pandas zuvor gebeten haben, die Spalte zu summieren, warfare dies der Fall verkettete Zeichenfolgen Anstatt Zahlen hinzuzufügen:
Diese Artwork von Downside tritt überraschend häufig auf, wenn mit echten Datensätzen gearbeitet wird. Aus Tabellenkalkulationen, CSV-Dateien oder APIs exportierte Daten speichern Zahlen häufig als Textual content.
Der sicherste Ansatz ist Definieren Sie Datentypen explizit, anstatt sich auf die Vermutungen von Pandas zu verlassen.
Wir können die Spalte mit reparieren astype():
orders("income") = orders("income").astype(int)
Wenn wir nun die Typen noch einmal überprüfen:
orders.dtypes
Wir bekommen:
order_id int64
customer_id int64
income int64
low cost float64
dtype: object
Und die Berechnung verhält sich schließlich wie erwartet:
orders("income").sum()
Ausgabe:
750
Eine einfache Verteidigungsgewohnheit
Immer wenn ich jetzt einen neuen Datensatz lade, ist eines der ersten Dinge, die ich ausführe:orders.data()
Es gibt einen schnellen Überblick über:
- Spaltendatentypen
- fehlende Werte
- Speichernutzung
Dieser einfache Schritt deckt oft subtile Probleme auf bevor sie sich später in verwirrende Bugs verwandeln.
Aber Datentypen sind nur ein Teil der Geschichte.
Ein weiteres Pandas-Verhalten sorgt für noch mehr Verwirrung – insbesondere beim Kombinieren von Datensätzen oder beim Durchführen von Berechnungen.
Es ist etwas namens Indexausrichtung.
Indexausrichtung: Pandas stimmt mit Beschriftungen überein, nicht mit Zeilen
Eines der mächtigsten – und verwirrendsten – Verhaltensweisen bei Pandas ist Indexausrichtung.
Wenn Pandas Operationen zwischen Objekten (wie Serien oder DataFrames) ausführt, ist dies der Fall stimmt nicht mit den Zeilen nach Place überein.
Stattdessen ordnet es ihnen zu Indexbezeichnungen.
Das erscheint zunächst subtil. Aber es kann leicht zu Ergebnissen kommen, die auf den ersten Blick richtig erscheinen, in Wirklichkeit aber falsch sind.
Sehen wir uns ein einfaches Beispiel an.
income = pd.Collection((120, 250, 80), index=(0, 1, 2))
low cost = pd.Collection((10, 20, 5), index=(1, 2, 3))
income + low cost
Das Ergebnis sieht so aus:
0 NaN
1 260
2 100
3 NaN
dtype: float64
Auf den ersten Blick könnte sich das seltsam anfühlen.
Warum produzierte Pandas vier statt drei Reihen?
Der Grund dafür ist, dass Pandas die Werte angeglichen hat basierend auf Indexbezeichnungen.
Pandas richtet Werte anhand ihrer Indexbezeichnungen aus. Intern sieht die Berechnung so aus:
- Bei Index 0Umsatz vorhanden, aber Rabatt nicht → Ergebnis wird
NaN - Bei Index 1beide Werte existieren →
250 + 10 = 260 - Bei Index 2beide Werte existieren →
80 + 20 = 100 - Bei Index 3Rabatt vorhanden, aber Umsatz nicht → Ergebnis wird
NaN
Was ergibt:
0 NaN
1 260
2 100
3 NaN
dtype: float64
Zeilen ohne übereinstimmende Indizes führen zu fehlenden Werten. grundsätzlich.
Dieses Verhalten ist tatsächlich eine der Stärken von Pandas, denn es ermöglicht die intelligente Kombination von Datensätzen mit unterschiedlichen Strukturen.
Es können aber auch subtile Fehler auftreten.
Wie sich dies in der realen Analyse zeigt
Kehren wir zu unserem zurück orders Datensatz.
Angenommen, wir filtern Bestellungen mit Rabatten:
discounted_orders = orders(orders("low cost").notna())
Stellen Sie sich nun vor, wir versuchen zu rechnen Nettoumsatz durch Abzug des Rabatts.
orders("income") - discounted_orders("low cost")
Sie könnten eine einfache Subtraktion erwarten.
Stattdessen richtet Pandas Zeilen mithilfe von aus Originalindizes.
Das Ergebnis enthält fehlende Werte, da der gefilterte Datenrahmen nicht mehr dieselbe Indexstruktur aufweist.
Dies kann leicht dazu führen:
- unerwartet
NaNWerte - falsch berechnete Kennzahlen
- verwirrende nachgelagerte Ergebnisse
Und noch einmal – Pandas wird keinen Fehler auslösen.
Ein defensiver Ansatz
Wenn Sie möchten, dass sich Vorgänge verhalten Reihe für ReiheEine gute Vorgehensweise besteht darin, den Index nach dem Filtern zurückzusetzen.
discounted_orders = orders(orders("low cost").notna()).reset_index(drop=True)
Jetzt werden die Zeilen wieder nach Place ausgerichtet.
Eine weitere Möglichkeit besteht darin, Objekte vor dem Ausführen von Vorgängen explizit auszurichten:
orders.align(discounted_orders)
Oder in Situationen, in denen eine Ausrichtung nicht erforderlich ist, können Sie mit Roharrays arbeiten:
orders("income").values
Am Ende läuft alles darauf hinaus.
In Pandas werden Operationen nach ausgerichtet Indexbezeichnungennicht Zeilenreihenfolge.
Das Verständnis dieses Verhaltens hilft, viele Rätsel zu erklären NaN Werte, die während der Analyse angezeigt werden.
Aber es gibt noch ein anderes Pandas-Verhalten, das quick jeden Datenanalysten irgendwann verwirrt hat.
Sie haben es wahrscheinlich schon einmal gesehen:<sturdy>SettingWithCopyWarning</sturdy>
Lassen Sie uns herausfinden, was dort tatsächlich passiert.
Großartig – fahren wir mit dem nächsten Abschnitt fort.
Das Copy-vs-View-Downside (und die berühmte Warnung)
Wenn Sie Pandas schon länger verwenden, haben Sie diese Warnung wahrscheinlich schon einmal gesehen:
SettingWithCopyWarning
Als ich zum ersten Mal darauf stieß, habe ich es größtenteils ignoriert. Der Code lief immer noch und die Ausgabe sah intestine aus, additionally schien es keine große Sache zu sein.
Diese Warnung weist jedoch auf etwas Wichtiges an der Funktionsweise von Pandas hin: Manchmal ändern Sie das Originaldatenrahmenund manchmal modifizieren Sie a temporäre Kopie.
Das Schwierige daran ist, dass Pandas dies nicht immer deutlich macht.
Schauen wir uns ein Beispiel anhand unseres an orders Datensatz.
Angenommen, wir möchten den Umsatz für Bestellungen anpassen, für die ein Rabatt besteht.
Ein natürlicher Ansatz könnte so aussehen:
discounted_orders = orders(orders("low cost").notna())
discounted_orders("income") = discounted_orders("income") - discounted_orders("low cost")
Dies löst häufig die Warnung aus:
SettingWithCopyWarning:
Es wird versucht, einen Wert für eine Kopie eines Slice aus einem DataFrame festzulegen
Das Downside ist das discounted_orders ist möglicherweise kein unabhängiger Datenrahmen. Es könnte nur ein sein Sicht ins Authentic orders Datenrahmen.
Wenn wir sie additionally ändern, ist sich Pandas nicht immer sicher, ob wir beabsichtigen, die Originaldaten oder die gefilterte Teilmenge zu ändern. Diese Mehrdeutigkeit erzeugt die Warnung.
Schlimmer noch, die Änderung könnte sein sich nicht konsequent verhalten abhängig davon, wie der Datenrahmen erstellt wurde. In manchen Situationen wirkt sich die Änderung auf den ursprünglichen Datenrahmen aus; in anderen Fällen ist dies nicht der Fall.
Diese Artwork von unvorhersehbarem Verhalten ist genau die Artwork von Dingen, die subtile Fehler in realen Datenworkflows verursachen.
Der sicherere Weg: Verwenden .loc
Ein zuverlässigerer Ansatz besteht darin, den Datenrahmen zu ändern explizit verwenden .loc.
orders.loc(orders("low cost").notna(), "income") = (
orders("income") - orders("low cost")
)
Diese Syntax teilt Pandas klar mit, welche Zeilen geändert und welche Spalte aktualisiert werden soll. Da der Vorgang explizit ist, kann Pandas die Änderung sicher und ohne Mehrdeutigkeit anwenden.
Eine weitere gute Angewohnheit: Verwenden .copy()
Manchmal möchte man wirklich mit einem separaten Datenrahmen arbeiten. In diesem Fall ist es am besten, eine explizite Kopie zu erstellen.
discounted_orders = orders(orders("low cost").notna()).copy()
Jetzt discounted_orders ist ein völlig unabhängiges Objekt und eine Änderung hat keine Auswirkungen auf den Originaldatensatz.
Bisher haben wir gesehen, wie drei Verhaltensweisen nonetheless und leise Probleme verursachen können:
- falsch Datentypen
- unerwartet Indexausrichtung
- mehrdeutig Kopier- und Ansichtsvorgänge
Aber es gibt noch eine weitere Angewohnheit, die die Zuverlässigkeit Ihrer Daten-Workflows erheblich verbessern kann.
Daran denken viele Datenanalysten selten: defensive Datenmanipulation.
Defensive Datenmanipulation: Pandas-Code schreiben, der lautstark fehlschlägt
Das ist mir bei der Arbeit mit Daten langsam klar geworden Die meisten Probleme sind nicht auf Codeabstürze zurückzuführen.
Sie stammen aus Code, der erfolgreich ausgeführt wird, aber das erzeugt falsche Zahlen.
Und bei Pandas kommt das überraschend häufig vor, da die Bibliothek flexibel gestaltet ist. Es hält Sie selten davon ab, etwas Fragwürdiges zu tun.
Aus diesem Grund verlassen sich viele Dateningenieure und erfahrene Analysten auf etwas namens defensive Datenmanipulation.
Hier ist die Idee.
Anstatt davon auszugehen, dass Ihre Daten korrekt sind, handeln Sie aktiv Validieren Sie Ihre Annahmen während Sie arbeiten.
Dadurch können Sie Probleme frühzeitig erkennen, bevor sie sich unbemerkt durch Ihre Analyse oder Pipeline ausbreiten.
Schauen wir uns ein paar praktische Beispiele an.
Validieren Sie Ihre Datentypen
Vorhin haben wir gesehen, wie das income Die Spalte sah numerisch aus, wurde aber tatsächlich als Textual content gespeichert. Eine Möglichkeit, dies zu verhindern, besteht darin, Ihre Annahmen explizit zu überprüfen.
Zum Beispiel:
assert orders("income").dtype == "int64"
Wenn der dtype falsch ist, löst der Code sofort einen Fehler aus.
Dies ist viel besser, als das Downside später zu entdecken, wenn Ihre Messwerte nicht stimmen.
Verhindern Sie gefährliche Fusionen
Eine weitere häufige Quelle stiller Fehler ist das Zusammenführen von Datensätzen.
Stellen Sie sich vor, wir fügen einen kleinen Kundendatensatz hinzu:
prospects = pd.DataFrame({
"customer_id": (1, 2, 3),
"metropolis": ("Lagos", "Abuja", "Ibadan")
})
Eine typische Zusammenführung könnte so aussehen:
orders.merge(prospects, on=“customer_id“)
Das funktioniert intestine, es besteht jedoch ein verstecktes Risiko.
Wenn die Schlüssel nicht eindeutig sind, kann es bei der Zusammenführung versehentlich zu einer Erstellung kommen doppelte Zeilenwas Kennzahlen wie die Gesamteinnahmen in die Höhe treibt.
Pandas bietet hierfür eine sehr nützliche Absicherung:
orders.merge(prospects, on="customer_id", validate="many_to_one")
Jetzt gibt Pandas einen Fehler aus, wenn die Beziehung zwischen den Datensätzen nicht Ihren Erwartungen entspricht.
Dieser kleine Parameter kann später ein sehr mühsames Debuggen verhindern.
Überprüfen Sie frühzeitig, ob Daten fehlen
Fehlende Werte können auch zu unerwartetem Verhalten bei Berechnungen führen.
Eine schnelle Diagnoseprüfung kann dabei helfen, Probleme sofort aufzudecken:
orders.isna().sum()
Dies zeigt, wie viele fehlende Werte in jeder Spalte vorhanden sind.
Bei großen Datensätzen können diese kleinen Überprüfungen schnell Probleme aufdecken, die andernfalls möglicherweise unbemerkt bleiben würden.
Ein einfacher Verteidigungsworkflow
Mit der Zeit habe ich begonnen, einer kleinen Routine zu folgen, wenn ich mit einem neuen Datensatz arbeite:
- Untersuchen Sie die Struktur
df.data() - Datentypen korrigieren
astype() - Überprüfen Sie fehlende Werte
df.isna().sum() - Validieren Sie Zusammenführungen
validate="one_to_one" or "many_to_one" - Verwenden
.locbeim Ändern von Daten
Diese Schritte dauern nur wenige Sekunden, verringern jedoch die Wahrscheinlichkeit, dass stille Fehler auftreten, erheblich.
Letzte Gedanken
Als ich anfing, Pandas zu lernen, konzentrierten sich die meisten Tutorials auf leistungsstarke Operationen wie groupby, mergeoder pivot_table.
Diese Instruments sind wichtig, aber mir ist klar geworden, dass zuverlässige Datenarbeit genauso stark vom Verständnis abhängt wie sich Pandas unter der Haube verhält.
Konzepte wie:
- Datentypen
- Indexausrichtung
- Kopier- vs. Ansichtsverhalten
- defensive Datenmanipulation
Vielleicht fühlt es sich zunächst nicht aufregend an, aber sie sind genau die Dinge, die Daten-Workflows aufrecht erhaltenstabil und vertrauenswürdig.
Die größten Fehler bei der Datenanalyse entstehen selten durch abstürzenden Code.
Sie stammen aus Code, der perfekt läuft – und dabei stillschweigend falsche Ergebnisse liefert.
Und das Verständnis dieser Pandas-Grundlagen ist eine der besten Möglichkeiten, dies zu verhindern.
Danke fürs Lesen! Wenn Sie diesen Artikel hilfreich fanden, lassen Sie es mich gerne wissen. Ich freue mich sehr über Ihr Suggestions
