Datenüberwachung in Python: Funktion zur Verfolgung von Änderungen der Spaltensummen
Beim Verarbeiten von Daten in pandas ist es leicht, Änderungen bei Schlüsselmessgrößen aufgrund von Fehlern in Merge- oder Groupby-Operationen zu übersehen. Die det_sum-Funktion berechnet nicht nur die Spaltensumme, sondern verfolgt auch Abweichungen zwischen den Aufrufen und hilft so, Anomalien im ETL-Prozess zu erkennen.
Warum Spaltensummen überwachen?
Bei der Datenverarbeitung ist es entscheidend, die Stabilität von Schlüsselmessgrößen im Blick zu behalten. Eine Merge-Operation mit falschen Schlüsseln kann das Datenvolumen unerwartet aufblasen, während Groupby mit fehlenden Werten es schrumpfen lässt. Finanzkennzahlen sind besonders anfällig: Springt die Umsumme plötzlich um 15 %, ist das ein Warnsignal für ein Problem in der Verarbeitungspipeline. Der Standardansatz mit df['sales'].sum() reicht nicht – er liefert nur eine rohe Zahl ohne Änderungskontext und erfordert manuelle Vergleiche über die Phasen hinweg.
Die det_sum-Funktion automatisiert das Ganze und bietet:
- Automatische Formatierung großer Zahlen
- Vergleich mit dem vorherigen Wert
- Praktische Tabellenidentifikation
- Lesbare Warnungen bei Abweichungen
Architektur der det_sum-Funktion
Die Implementierung nutzt drei globale Variablen, um den Zustand zwischen Aufrufen zu halten:
_previous_sum = None
_case_number = 0
_table_names = {}
Die Funktion nimmt zwei Parameter: ein DataFrame und einen Spaltennamen. Wichtige Schritte:
- Prüfen, ob die Spalte existiert
- Aktuelle Summe berechnen
- Zahl formatieren
- Eindeutigen Tabellencodenamen erzeugen
- Mit vorherigem Wert vergleichen
Der Code balanciert Funktionalität und Einfachheit:
def det_sum(table, column):
import pandas as pd
import random
global _previous_sum, _case_number, _table_names
_case_number += 1
if column not in table.columns:
print(f"\n🔍 Summary №{_case_number}: Andryukha! The column disappeared '{column}'! Possible crime! Saddle up!")
return
current_sum = table[column].sum()
def format_number(num):
abs_num = abs(num)
if abs_num >= 1_000_000_000:
return f"{num/1_000_000_000:.1f} billion"
elif abs_num >= 1_000_000:
return f"{num/1_000_000:.1f} mln"
elif abs_num >= 1_000:
return f"{num/1_000:.1f} thousand"
else:
return f"{num:.1f}"
formatted_current = format_number(current_sum)
table_id = id(table)
if table_id not in _table_names:
animals = ["Antelope", "Beaver", "Badger", "Wolf", "Otter", "Cheetah", "Gorilla", "Porcupine", "Dolphin",
"Raccoon", "Giraffe", "Zebra", "Hare", "Iguana", "Yemeni chameleon", "Cat", "Kangaroo",
"Lev", "Llama", "Bear", "Walrus", "Rhinoceros", "Deer", "Panda", "Puma",
"Lynx", "Elephant", "Meerkat", "Tiger", "Seal", "Platypus", "Flaamimingo", "Hamster",
"Heron", "Turtle", "Chimpanzee", "Pike", "Emu", "Brambling", "Yak"]
_table_names[table_id] = random.choice(animals)
table_code = _table_names[table_id]
print(f"\n🕵️ Summary AN №{_case_number}: Onservation for object '{table_code}' by column '{column}'")
print("=" * 50)
if _previous_sum is None:
print(f"🔎 Object '{table_animal}' was accepted under observation! Amount: {formatted_current}")
print("📋 Fiksiruem in svodke...")
else:
print(f"💼 Tekuschaya sum: {formatted_current}")
difference = current_sum - _previous_sum
if difference != 0:
formatted_diff = f"{abs(difference):,.0f}".replace(',', ' ')
if difference > 0:
print(f"⬆️ Hmm... Amount wzrosla on {formatted_diff}")
print("🕵️ Looks like, we missed new connection! Sending crew for kontrole!")
else:
print(f"⬇️ Wow! Amount decreased on {formatted_diff}")
print("🔍 Who-then is trying to cover tracks! Need check by cameras!")
else:
print("🤔 Amount not changed...")
print("📝 Zanosim in svodku: Object not outputil, meetings not recorded")
print("=" * 50)
_previous_sum = current_sum
Zahlenformatierung für bessere Lesbarkeit
Ein Hauptproblem bei der Standard-Summeausgabe ist die schlechte Lesbarkeit großer Zahlen. Die format_number-Funktion löst das, indem sie 1500000 zu "1,5 Mio." umwandelt. Der Algorithmus:
- Für Werte ≥ 1 Milliarde: durch 10^9 teilen, auf Zehntelstellen runden
- Für Werte ≥ 1 Million: durch 10^6 teilen
- Für Tausender: durch 10^3 teilen
- Sonstige: mit einer Nachkommastelle anzeigen
Das ist bei Finanzdaten essenziell, wo Milliarden alltäglich sind. Die Formatierung läuft automatisch, ohne extra Aufrufe, und beschleunigt die Analyse.
Eindeutige Tabellenidentifikation
Da pandas keinen direkten Zugriff auf den Variablennamen eines DataFrames bietet, greift die Funktion zu einem cleveren Trick: der Speicher-ID (id(table)). Beim ersten Aufruf wählt sie ein zufälliges Tier aus einer festen Liste. Das ermöglicht:
- Nachverfolgung mehrerer Tabellen in einem Skript
- Unabhängige Änderungshistorie pro Tabelle
- Vermeidung von Verwechslungen bei Transformationen (Quelltabellennamen ändern sich oft)
Die Tierre Liste umfasst 40 Optionen, von Antilope bis Yak. Wiederholte Aufrufe für dieselbe Tabelle nutzen den gespeicherten Namen für konsistente Logs.
Integration in den Workflow
Für den Dauereinsatz die Funktion in ein separates Modul auslagern. Empfohlenes Setup:
- config/func.py erstellen
- Den det_sum-Code dort einfügen
- Im Hauptskript importieren:
import importlib
import config.func
importlib.reload(config.func)
from config.func import det_sum
Das Neuladen mit importlib.reload übernimmt Änderungen ohne Kernel-Neustart. Dieser Ansatz:
- Reduziert Code-Duplikate
- Zentralisiert Hilfsfunktionen
- Hält das Hauptskript übersichtlich
Was zählt
- Globale Variablen für Zustand: _previous_sum und _case_number verfolgen Änderungen über Aufrufe hinweg, aber Vorsicht in Multithreading-Umgebungen.
- Sichere Prüfungen: Die Funktion checkt zuerst die Spaltenexistenz und verhindert Abstürze.
- Menschzentrierte Ausgabe: Formatierung und thematische Meldungen erleichtern die Fehlersuche ohne manuelles Log-Wühlen.
- Identifikation via id(): Dieser Pandas-Workaround trackt Tabellen zuverlässig in einer Sitzung.
- Flexible Integration: Kein Pipeline-Umbau nötig – det_sum-Aufrufe einfach einbauen.
Dieses Tool eignet sich hervorragend zum Debuggen komplexer ETL-Prozesse, bei denen Datenänderungen vorhersehbar sein müssen. Mit nur 30 Zeilen schließt es eine kritische Lücke in der Datenüberwachung.
— Editorial Team
Noch keine Kommentare.