Auditar un conjunt de dades amb Python en cinc minuts
ydata-profiling genera un informe HTML amb duplicats, valors buits, cardinalitat i correlacions. I les comprovacions que has de fer a mà després.
·8 min de lectura
Abans de migrar dades, integrar-les amb un altre sistema o construir-hi res a sobre, s’han de mirar. No «obrir el fitxer i fer scroll»: mirar de veritat, amb números.
Aquest article explica com fer aquesta auditoria en cinc minuts amb ydata-profiling, i després què has de comprovar tu perquè cap eina automàtica t’ho dirà.
Què és
ydata-profiling (abans pandas-profiling) agafa un DataFrame de pandas i escup un fitxer HTML autocontingut amb l’anàlisi complet: una fitxa per variable, recompte de duplicats, mapa de valors absents, correlacions i una llista d’avisos.
És una eina d’exploració, no de validació contínua. Serveix per entendre què tens al davant el primer dia.
Instal·lar-lo i executar-lo
python -m venv .venv && source .venv/bin/activate
pip install ydata-profiling
I l’ús mínim, que ja val la pena:
import pandas as pd
from ydata_profiling import ProfileReport
df = pd.read_csv('clients.csv', dtype=str, keep_default_na=False, na_values=[''])
perfil = ProfileReport(df, title='Auditoria de clients', explorative=True)
perfil.to_file('informe.html')
Obre informe.html al navegador i ja hi ets.
Per què dtype=str
Aquesta línia és la més important de les quatre. Per defecte, pandas endevina el tipus de cada columna, i endevina malament exactament on més mal fa:
- Un codi de client
0042es converteix en el número42i perds els zeros. - Una columna de NIFs que casualment només conté números en aquest fitxer es torna numèrica i deixa de casar amb la del sistema de destí.
- Un telèfon
+34 600 …en una fila i600…en una altra fa que tota la columna es quedi com a text… o no, segons quantes files miri pandas.
Llegint-ho tot com a text veus el que hi ha realment al fitxer, que és el que has d’auditar. Els tipus ja els posaràs després, a consciència.
El keep_default_na=False amb na_values=[''] evita l’altre clàssic: que pandas converteixi la cadena "NA", "None" o "null" —que pot ser un valor legítim— en un buit.
Què has de mirar de l’informe, i en quin ordre
L’informe és llarg. Aquest és l’ordre que fa que sigui útil.
1. La secció «Alerts»
És on va tot el que l’eina considera sospitós, i és la millor manera d’atacar-lo. Les etiquetes que importen:
| Avís | Què vol dir | Per què t’importa |
|---|---|---|
Duplicates |
Hi ha files completament idèntiques | Migrar-les duplica registres a destí |
Constant |
La columna té sempre el mateix valor | No aporta res; sovint és un camp que es va deixar de fer servir |
Unique |
Tots els valors són diferents | Candidata a clau primària |
High cardinality |
Moltíssims valors diferents | Text lliure disfressat de categoria |
Missing |
Molts buits | Cal decidir si és un error o un «no aplica» |
Zeros |
Molts zeros | Sovint són buits mal codificats |
Imbalance |
Una categoria s’ho menja tot | El 98 % «Actiu» sol voler dir que ningú manté el camp |
2. Overview → Duplicate rows
Et diu quantes files són completament idèntiques. Si en surten, la pregunta abans d’esborrar-les no és «com les trec» sinó per què n’hi ha: si el fitxer prové d’una exportació, sovint és un JOIN mal fet a origen, i esborrar-les amaga un problema que tornarà al pròxim volcat.
3. La fitxa de cada variable
Per a cada columna tens Distinct, Distinct (%), Missing, i per a les de text la llista de valors més freqüents. Aquí és on descobreixes que el camp «Província» té 63 valors diferents per a 52 províncies, perquè hi ha Barcelona, BARCELONA i Barcelona amb espai.
Mira’t sempre els valors més freqüents i els menys freqüents de cada columna categòrica. La cua és on viuen els errors.
4. Missing values
Quatre gràfics: el recompte per columna, la matriu (quines files tenen buits, i on), el dendrograma i el mapa de calor de coocurrència. Aquest últim és el més infravalorat: et diu quins buits van junts. Si Email i Telèfon estan buits sempre a les mateixes files, no tens dos problemes de qualitat: tens un grup de registres que va entrar per una altra via.
5. Correlacions
Útil sobretot per detectar columnes redundants: dues que sempre van juntes solen ser la mateixa cosa escrita de dues maneres, i una de les dues es pot deixar de mantenir.
Quan el fitxer és gran
L’informe complet calcula correlacions i interaccions entre totes les parelles de columnes, i això escala malament. Amb centenars de milers de files o desenes de columnes:
perfil = ProfileReport(df, title='Auditoria', minimal=True)
minimal=True desactiva correlacions, interaccions i mostres de text detallades. Segueix donant-te recomptes, buits, duplicats i distribucions, que és el 80 % del valor.
Una alternativa és auditar una mostra representativa i deixar els recomptes exactes per a les comprovacions manuals de la secció següent:
perfil = ProfileReport(df.sample(50_000, random_state=0), minimal=True)
Comparar dos volcats
Aquesta funció és poc coneguda i molt útil quan reps el mateix fitxer cada mes:
anterior = ProfileReport(df_juliol, title='Juliol')
actual = ProfileReport(df_agost, title='Agost')
anterior.compare(actual).to_file('comparativa.html')
Et posa les dues auditories una al costat de l’altra. És la manera més ràpida de veure que aquest mes ha aparegut una categoria nova, o que una columna que sempre venia plena ara ve buida al 30 %.
El que has de comprovar tu
Cap eina automàtica sap quines són les regles del teu negoci. Aquestes quatre comprovacions són manuals i són les que decideixen si les dades es poden migrar.
La clau única, de veritat
L’informe et dirà si una columna és Unique en aquest fitxer. Això no vol dir que sigui una clau: vol dir que en aquestes files no s’ha repetit. Comprova-ho explícitament, i comprova també les claus compostes:
def es_clau(df, columnes):
total = len(df)
unics = len(df.drop_duplicates(subset=columnes))
buits = df[columnes].isna().any(axis=1).sum()
return {'files': total, 'combinacions': unics,
'repetides': total - unics, 'amb_buits': int(buits)}
print(es_clau(df, ['nif']))
print(es_clau(df, ['client_id', 'any', 'mes']))
Una clau amb buits no és una clau, encara que no es repeteixi cap valor.
La densitat, columna a columna
Quin percentatge de cada camp ve informat:
densitat = df.notna().mean().sort_values()
print((densitat * 100).round(1).to_string())
Ordenat de menys a més, la part de dalt de la llista és la conversa que has de tenir amb qui et dona les dades: «aquest camp ve informat al 4 %; el fem servir o el deixem anar?»
La integritat referencial
Abans de qualsevol integració, els identificadors d’una taula han d’existir a l’altra:
orfes = set(comandes['client_id']) - set(clients['client_id'])
print(f'{len(orfes)} clients referenciats que no existeixen')
print(list(orfes)[:10])
Aquest número és gairebé sempre més gran que zero, i gairebé sempre sorprèn.
Els formats dins d’una mateixa columna
Una manera ràpida de veure quantes maneres diferents d’escriure el mateix conviuen a una columna: substituir cada dígit per 9 i cada lletra per A, i comptar patrons.
patrons = (df['telefon'].fillna('')
.str.replace(r'\d', '9', regex=True)
.str.replace(r'[A-Za-zÀ-ÿ]', 'A', regex=True)
.value_counts())
print(patrons.head(15))
Si surten dotze patrons per a una columna de telèfons, ja saps quanta feina de normalització tens al davant — i, sobretot, la tens quantificada.
Després de l’exploració, la validació
ydata-profiling és per al primer dia. Quan les regles ja les tens clares i el fitxer arriba cada mes, el que vols és que el procés s’aturi sol si les incompleix. Això ho fa pandera, amb un esquema declarat al codi:
import pandera.pandas as pa
esquema = pa.DataFrameSchema({
'nif': pa.Column(str, pa.Check.str_matches(r'^[0-9]{8}[A-Z]$'), unique=True),
'email': pa.Column(str, pa.Check.str_contains('@'), nullable=True),
'import': pa.Column(float, pa.Check.ge(0)),
})
esquema.validate(df, lazy=True) # lazy=True: recull tots els errors, no només el primer
Amb lazy=True, l’excepció que llança porta a dins la taula de totes les files que fallen i per què. Aquest és el fitxer que envies a qui genera les dades.
En resum
ProfileReport(df).to_file('informe.html')per veure què tens.- Llegeix el fitxer com a text i mira els avisos abans que res.
- Les claus, la densitat, els orfes i els formats, comprova’ls tu.
- Quan les regles siguin estables, passa de l’exploració a
panderai deixa que el procés es queixi sol.
Cinc minuts d’això abans de començar estalvien la setmana de descobrir a mitja migració que la clau no era clau.