Surveillance des données en Python : Fonction pour suivre les changements de sommes de colonnes
Lors du traitement des données avec pandas, il est facile de passer à côté des changements dans les métriques clés en raison d'erreurs dans les opérations de jointure ou de groupby. Présentons la fonction det_sum, qui non seulement calcule la somme de la colonne, mais suit aussi les écarts entre les appels, aidant à détecter les anomalies dans le processus ETL.
Pourquoi surveiller les sommes de colonnes ?
Dans le traitement des données, il est crucial de suivre la stabilité des métriques clés. Par exemple, une opération de jointure avec des clés incorrectes peut gonfler de manière inattendue le volume de données, tandis qu'un groupby avec des valeurs manquantes peut le réduire. Les métriques financières sont particulièrement vulnérables : si la somme des ventes change soudainement de 15 %, c'est un signal d'alarme pour un problème dans la chaîne de traitement. L'approche standard avec df['sales'].sum() est insuffisante — elle affiche un nombre brut sans contexte de changement et nécessite des comparaisons manuelles entre les étapes.
La fonction det_sum automatise cela en ajoutant :
- Formatage automatique des grands nombres
- Comparaison avec la valeur précédente
- Identification pratique de la table
- Alertes d'écart lisibles par un humain
Architecture de la fonction det_sum
L'implémentation repose sur trois variables globales pour maintenir l'état entre les appels :
_previous_sum = None
_case_number = 0
_table_names = {}
La fonction prend deux paramètres : un DataFrame et un nom de colonne. Étapes clés :
- Vérifier si la colonne existe
- Calculer la somme actuelle
- Formater le nombre
- Générer un nom de code unique pour la table
- Comparer avec la valeur précédente
Le code équilibre fonctionnalité et simplicité :
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
Formatage des nombres pour la lisibilité
Un problème clé avec la sortie standard de sum est l'illisbilité des grands nombres. La fonction format_number corrige cela en transformant 1500000 en « 1,5 mln ». L'algorithme :
- Pour les valeurs ≥ 1 milliard : diviser par 10^9, arrondir à la dixième
- Pour les valeurs ≥ 1 million : diviser par 10^6
- Pour les milliers : diviser par 10^3
- Autres : afficher avec une décimale
Ceci est particulièrement vital pour les données financières, où les milliards sont courants. Le formatage se fait automatiquement sans appels supplémentaires, accélérant l'analyse.
Identification unique des tables
Puisque pandas ne permet pas d'obtenir directement le nom de la variable DataFrame, la fonction utilise un astucieux truc : l'ID mémoire (id(table)). Au premier accès, elle choisit un animal au hasard dans une liste prédéfinie. Cela permet :
- Suivre plusieurs tables dans un même script
- Maintenir l'historique des changements par table indépendamment
- Éviter la confusion pendant les transformations (les noms de tables sources changent souvent)
La liste d'animaux en compte 40, de l'Antilope au Yak. Les appels répétés pour la même table réutilisent le nom sauvegardé pour la cohérence des logs.
Intégration dans le workflow
Pour une utilisation continue, placez la fonction dans un module séparé. Configuration recommandée :
- Créer config/func.py
- Ajouter le code det_sum là
- Importer dans le script principal :
import importlib
import config.func
importlib.reload(config.func)
from config.func import det_sum
Le rechargement via importlib.reload applique les changements sans redémarrer le kernel. Cette approche :
- Réduit la duplication de code
- Centralise les utilitaires
- Garde le script principal propre
Ce qui compte
- Variables globales pour l'état : _previous_sum et _case_number suivent les changements entre les appels, mais prudence en environnement multithreadé.
- Vérifications sécurisées : La fonction vérifie d'abord l'existence de la colonne, évitant les plantages pendant le traitement.
- Sortie orientée humain : Formatage des nombres et messages thématiques accélèrent le diagnostic des problèmes sans fouiller manuellement les logs.
- Identification via id() : Ce contournement pandas suit fiablement les tables dans une session unique.
- Intégration flexible : Pas besoin de remanier les pipelines — insérez simplement les appels det_sum où nécessaire.
Cet outil excelle pour déboguer les processus ETL complexes où les changements de données doivent être prévisibles. L'implémentation fait 30 lignes mais comble un manque critique en surveillance des données.
— Editorial Team
Aucun commentaire pour le moment.