Validazione dello schema e asserzioni
Scriva controlli con asserzioni sugli intervalli delle colonne, sui vincoli di non-null e sulle chiavi univoche, da eseguire all'inizio di ogni pipeline.
Validazione dello schema e asserzioni è una lezione Pandas & NumPy Academy gratuita su CoddyKit. Questa è la lezione 4 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Pandas & NumPy Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Pandas & NumPy Academy include 4 lezioni in totale.
Perché la convalida dello schema è importante
Una pipeline di dati elabora automaticamente nuovi dati, spesso senza alcuna revisione umana. Se lo schema del file di input cambia — una colonna viene rinominata, il formato di una data varia oppure compare una nuova categoria — la pipeline dovrebbe fallire in modo evidente invece di produrre un output errato senza segnalarlo. La convalida dello schema tramite asserzioni è il meccanismo che impone i contratti tra produttori e consumatori di dati, rilevando i problemi nel momento più precoce possibile.
import pandas as pd
import numpy as np
df = pd.read_parquet('sales_treated.parquet')
print('Loaded:', df.shape)
print(df.dtypes)Controlli sulle colonne obbligatorie
La convalida più fondamentale consiste nel verificare che siano presenti tutte le colonne obbligatorie. Memorizzi l'insieme di colonne previsto nella configurazione e verifichi con un'asserzione che sia un sottoinsieme delle colonne effettive. Questo controllo rileva immediatamente rinominazioni e rimozioni all'avvio della pipeline, prima che il codice a valle tenti di accedere a colonne mancanti generando un errore KeyError difficile da interpretare nel mezzo della pipeline.
REQUIRED_COLUMNS = {'order_id', 'order_date', 'customer_id',
'product', 'category', 'quantity', 'unit_price', 'revenue'}
missing = REQUIRED_COLUMNS - set(df.columns)
assert not missing, f'Missing required columns: {missing}'
print('All required columns present.')Asserzioni sui tipi di dati delle colonne
Dopo aver verificato le colonne obbligatorie, convalidi i relativi tipi di dati. Una colonna di date caricata come object indica che non è stato chiamato pd.to_datetime(). Una colonna di identificativi memorizzata come float invece di int64 indica spesso la presenza di valori NaN che ha impedito la memorizzazione come interi. Scriva asserzioni sui tipi utilizzando assert df['col'].dtype == expected_type per le colonne più importanti.
assert pd.api.types.is_datetime64_any_dtype(df['order_date']), \
'order_date must be datetime'
assert pd.api.types.is_numeric_dtype(df['revenue']), \
'revenue must be numeric'
assert df['order_id'].dtype == object or pd.api.types.is_integer_dtype(df['order_id']), \
'order_id must be string or int'
print('Dtype checks passed.')Vincoli sui valori non nulli
Le colonne chiave come order_id, order_date e revenue non dovrebbero mai contenere valori nulli. Per ciascuna di esse verifichi df['col'].notna().all(). Per rendere il messaggio dell'asserzione utile all'azione, includa il numero di valori nulli, così l'operatore della pipeline conoscerà l'entità del problema e non soltanto il fatto che un'asserzione non è stata soddisfatta.
NOT_NULL_COLS = ['order_id', 'order_date', 'revenue', 'customer_id']
for col in NOT_NULL_COLS:
null_count = df[col].isna().sum()
assert null_count == 0, f'{col} has {null_count} null values'
print('Non-null checks passed.')Controlli dell'intervallo per le colonne numeriche
Le colonne numeriche hanno spesso intervalli validi definiti dalle regole aziendali. Il ricavo non può essere negativo. La quantità deve essere un intero positivo. Il prezzo unitario deve essere maggiore di zero. Verifichi esplicitamente questi vincoli: una riga con ricavo negativo che superi i controlli ridurrà i totali in ogni aggregazione successiva senza generare errori. I controlli dell'intervallo rilevano tempestivamente gli errori di inserimento e i bug dei sistemi a monte.
assert (df['revenue'] >= 0).all(), 'Negative revenue found'
assert (df['quantity'] > 0).all() or df['is_return'].any(), \
'Non-positive quantity without return flag'
assert (df['unit_price'] > 0).all(), 'Zero or negative unit price found'
print('Range checks passed.')Asserzioni sulle chiavi univoche
Dopo la deduplicazione, order_id dovrebbe essere univoco. Verifichi df['order_id'].is_unique per assicurarsi che questo invariante venga mantenuto a ogni esecuzione della pipeline. Le violazioni dell'univocità dopo la deduplicazione indicano un bug nella logica di deduplicazione oppure una nuova origine dati che non è stata pulita prima dell'unione con il dataset principale.
assert df['order_id'].is_unique, \
f'order_id not unique: {df.duplicated(subset=["order_id"]).sum()} duplicates'
print('Uniqueness check passed.')Asserzioni sui valori categoriali
Per le colonne con un insieme finito di valori validi, come region o category, verifichi che ogni valore appartenga all'insieme consentito. In questo modo vengono rilevati valori anomali comparsi dopo una migrazione del sistema o una modifica nell'inserimento dei dati a monte. Definisca gli insiemi validi nella configurazione della pipeline, così sarà facile aggiornarli quando l'azienda si espanderà in nuove regioni.
VALID_REGIONS = {'North', 'South', 'East', 'West', 'Central'}
VALID_CATEGORIES = {'electronics', 'apparel', 'home', 'sports', 'beauty', 'other'}
assert df['region'].isin(VALID_REGIONS).all(), \
f'Invalid regions: {df[~df["region"].isin(VALID_REGIONS)]["region"].unique()}'
assert df['category'].isin(VALID_CATEGORIES).all(), \
'Invalid categories found'
print('Categorical checks passed.')Asserzioni sull'intervallo delle date
Verifichi che tutte le date rientrino nel periodo previsto per il dataset. Un ordine datato nel futuro è impossibile; un ordine precedente alla fondazione dell'azienda indica un record danneggiato. Definisca MIN_DATE e MAX_DATE nella configurazione e verifichi con un'asserzione che la colonna rientri nei limiti. Questo controllo rileva anche le date all'epoca Unix (1970-01-01) dovute a conversioni errate dei timestamp.
MIN_DATE = pd.Timestamp('2020-01-01')
MAX_DATE = pd.Timestamp('today')
assert (df['order_date'] >= MIN_DATE).all(), 'Date before minimum found'
assert (df['order_date'] <= MAX_DATE).all(), 'Future date found'
print(f'Date range: {df["order_date"].min()} to {df["order_date"].max()}')Controllo del numero di righe
Una variazione improvvisa nel numero di righe rispetto alla precedente esecuzione della pipeline è un forte segnale di un problema a monte. Memorizzi il numero di righe dell'esecuzione precedente in un file di configurazione e verifichi con un'asserzione che il nuovo conteggio rientri in un intervallo di tolleranza, ad esempio entro ±20% del conteggio storico. Un dataset che perde il 50% delle righe tra due esecuzioni indica quasi certamente un'esportazione dei dati non funzionante.
EXPECTED_MIN_ROWS = 5000
EXPECTED_MAX_ROWS = 200000
assert EXPECTED_MIN_ROWS <= len(df) <= EXPECTED_MAX_ROWS, \
f'Row count {len(df)} outside expected range [{EXPECTED_MIN_ROWS}, {EXPECTED_MAX_ROWS}]'
print(f'Row count check passed: {len(df)} rows')Raccolta dei controlli in una funzione validate
Raccolga tutte le asserzioni in un'unica funzione validate(df), che possa essere chiamata all'inizio di ogni fase della pipeline. Ogni controllo genera un AssertionError con un messaggio descrittivo se non viene superato. Questo modello rende la pipeline auto-documentante: la funzione di convalida costituisce il contratto dello schema, leggibile dalla macchina, per il DataFrame in quella fase.
def validate_sales_df(df):
assert not (REQUIRED_COLUMNS - set(df.columns)), 'Missing columns'
assert df['order_id'].is_unique, 'Duplicate order IDs'
assert (df['revenue'] >= 0).all(), 'Negative revenue'
assert df['region'].isin(VALID_REGIONS).all(), 'Invalid region'
print(f'Validation passed: {len(df)} rows, {len(df.columns)} columns')
validate_sales_df(df)Registrazione ordinata degli errori di convalida
Nelle pipeline di produzione, un arresto causato da un assert è accettabile durante lo sviluppo, ma è indesiderabile in un processo pianificato. Sostituisca le asserzioni isolate con blocchi try/except AssertionError che registrino il messaggio di errore e, facoltativamente, inviino un avviso prima di terminare. In questo modo il sistema di monitoraggio può acquisire il motivo dell'errore, invece di ricevere soltanto un traceback di eccezione non gestita.
import logging
logging.basicConfig(level=logging.INFO)
def validate_with_logging(df):
checks = [
(lambda d: d['order_id'].is_unique, 'Duplicate order IDs'),
(lambda d: (d['revenue'] >= 0).all(), 'Negative revenue found'),
]
for check_fn, msg in checks:
try:
assert check_fn(df), msg
except AssertionError as e:
logging.error(f'VALIDATION FAILED: {e}')
raise
validate_with_logging(df)
print('All checks passed.')Controllo rapido
Verifichi la Sua comprensione dei concetti di analisi dei dati trattati in questa lezione.
Riepilogo della lezione
In questa lezione ha imparato a: verificare con asserzioni le colonne obbligatorie, i dtypes, i vincoli sui valori non nulli e la validità degli intervalli, controllare le chiavi univoche, i valori categoriali e gli intervalli delle date e racchiudere tutti i controlli in una funzione validate() riutilizzabile con registrazione degli errori. Nel prossimo argomento esamineremo le aggregazioni personalizzate utilizzando apply() su colonne e righe.
Domande Frequenti
La lezione «Validazione dello schema e asserzioni» è gratuita?
Sì — il testo completo di «Validazione dello schema e asserzioni» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Pandas & NumPy Academy, passa a CoddyKit PRO. Il corso Pandas & NumPy Academy include 4 lezioni in totale.
Cosa imparerò in «Validazione dello schema e asserzioni»?
Scriva controlli con asserzioni sugli intervalli delle colonne, sui vincoli di non-null e sulle chiavi univoche, da eseguire all'inizio di ogni pipeline. Eserciti Pandas & NumPy Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare Pandas & NumPy Academy?
Non è richiesta alcuna esperienza precedente. Pandas & NumPy Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 4 di 4.
Quanto tempo richiede la lezione «Validazione dello schema e asserzioni»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione Pandas & NumPy Academy?
Sì. Ogni lezione Pandas & NumPy Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Rilevare e rimuovere i duplicati
- Rilevare e trattare gli outlier
- Uniformare le categorie incoerenti
- Validazione dello schema e asserzioni