Saltar al contenido

Indice / Practicas / EJ-5.2

EJ-5.2 · Limpieza integral de clientes

Tenés el padrón de clientes tal como salió del sistema: 120 filas con nombres mal tipeados, correos rotos, edades imposibles y campos vacíos. Hay que dejarlo usable, y dejar constancia de todo lo que se descartó.

Qué hay que hacer

A partir de un archivo de entrada, producir dos archivos de salida:

Nadie te va a decir cómo. Lo que sí está fijado, hasta el último detalle, es cómo tiene que quedar el resultado: eso es el contrato de más abajo. Cuando tu archivo coincida con el objetivo, terminaste.

ELI5Explicado facil

Te dan una lista de 120 clientes hecha un desastre y te piden dos listas nuevas: una con los que están bien y otra con los que tiraste, diciendo por qué.

La segunda lista es la parte que más se olvida y la más importante: si tirás 33 fichas y no anotás cuáles ni por qué, nadie puede revisar tu trabajo - ni vos mismo dentro de dos semanas.

Archivos

Cómo saber si te salió

Bajá el objetivo y comparar.py, y corré:

python comparar.py mi_salida.csv clientes_limpios.csv

Si dice OK, tu archivo es idéntico al esperado. Si no, te dice qué columna, qué fila y qué valor difiere. No hay nota ni entrega: es para vos.

Si te trabás con los tipos

Agregá --laxo para que compare solo los valores y no los tipos. Sirve para confirmar que tu lógica está bien antes de pelearte con int64 contra float64. Después sacalo y hacelo coincidir del todo.

Antes de arrancar, mirá los datos

clientes_crudos.csv (entrada) · 120 filas, se muestran 5
idnombrecorreoedadciudadfecha_alta
C0001José Pazjose.paz@example.com62Salta2025-02-20
C0002Lucía Peñalucia.pena@example.com48Salta2025-01-05
C0003Santiago Herrerasantiago.herrera@example.com40Salta2024-05-12
C0004José Rodríguezjose.rodriguez@example.com67Paraná2024-08-11
C0005Walter Gutiérrezwalter.gutierrez@example.com34Rosario2026-01-01

Fijate que la columna edad tiene de todo: números, la palabra treinta, un guion, campos vacíos y edades imposibles. Y que hay nombres con espacios de más y correos en mayúsculas.

El contrato de salida

Todo lo que sigue es obligatorio. Si dos personas resuelven el ejercicio bien, tienen que producir exactamente el mismo archivo; para eso está fijado el orden de las filas, el nombre y el orden de las columnas, y qué se hace con cada defecto.

clientes_limpios.csv · 87 filas

ColumnaTipoQue lleva
idtextoEl id original, sin tocar
nombretextoSin espacios sobrantes y con mayusculas iniciales: .strip().title()
correotextoSin espacios sobrantes y en minusculas: .strip().lower()
edadenteroEntre 18 y 100. Los ausentes ya vienen imputados
ciudadtextoLa ciudad, o 'Sin dato' si venia vacia
fecha_altatextoLa fecha tal cual, o vacio si era 0000-00-00
edad_imputadaentero1 si la edad la inventamos nosotros, 0 si vino en el archivo

Orden de las filas: id ascendente. Es unico, asi que no hace falta desempate. Indice: no se escribe: to_csv(index=False)

clientes_rechazados.csv · 33 filas

ColumnaTipoQue lleva
id_origentextoEl id de la fila descartada
columnatextoEn que columna estaba el problema
valor_originaltextoEl valor tal cual venia en el archivo, sin limpiar
motivotextoUno del vocabulario cerrado del curso

Orden de las filas: id_origen ascendente. Indice: no se escribe: to_csv(index=False)

Que hacer con cada defecto

DefectoDondeAccionAdonde va
nombre vacioC0044, C0091descartar descartarclientes_rechazados.csv con motivo ausente
correo vacioC0058, C0103descartar descartarclientes_rechazados.csv con motivo ausente
correo sin arrobacada 13 filasdescartar descartarclientes_rechazados.csv con motivo restriccion_violada
edad no numerica ('treinta')cada 31 filasdescartar descartarclientes_rechazados.csv con motivo no_numerico
edad fuera de 18 a 100 (15, 16, 17, 101, 128, 150, -5)cada 17, 19 y 23 filasdescartar descartarclientes_rechazados.csv con motivo fuera_de_rango
edad ausente (vacio, NaN, N/A, null, -)cada 29 filasimputar imputar con la mediana entera de las edades validas de las filas que sobreviven (da 46)clientes_limpios.csv con edad_imputada = 1
fecha_alta = 0000-00-00C0066, C0077conservar conservar la fila, vaciar el campoclientes_limpios.csv con fecha_alta vacia
ciudad vaciaC0088conservar conservar la fila, reemplazar por 'Sin dato'clientes_limpios.csv
nombre con espacios y en minusculas / correo en mayusculascada 7 y cada 11 filasnormalizar, normalizar, no descartarclientes_limpios.csv
Orden de comprobacion

Una fila puede tener mas de un problema. Se informa solo el primero de esta lista:

  1. nombre vacio
  2. correo vacio
  3. correo sin arroba
  4. edad no numerica
  5. edad fuera de rango

Una fila puede tener mas de un problema. Se informa SOLO el primero de esta lista, asi cada fila descartada aparece una unica vez y vale que limpios + rechazados = 120. Cambiar el orden cambia el archivo de rechazos aunque la limpieza sea la misma.

Conteos clave

Si estos numeros no te dan, algo se desvio antes de que llegues a comparar los archivos.

filas de entrada120
clientes_limpios.csv87
clientes_rechazados.csv33
edades imputadas3
mediana usada para imputar46
ciudades 'Sin dato'1
fechas vaciadas2
por motivofuera_de_rango: 18, restriccion_violada: 8, ausente: 4, no_numerico: 3

Invariantes

Comprobaciones que tu resultado tiene que cumplir. Corrilas vos mismo antes de comparar los archivos:

len(limpios) + len(rechazados) == 120
limpios['id'].is_unique
limpios['edad'].between(18, 100).all()
limpios['correo'].str.contains('@').all()
(limpios['nombre'].str.strip() != '').all()
limpios['edad_imputada'].sum() == 3
set(rechazados['motivo']) <= {'ausente', 'no_numerico', 'fuera_de_rango', 'restriccion_violada'}
rechazados['id_origen'].is_unique
PISTASSi te trabas, abri esto
  • Leer con dtype=str y keep_default_na=False es lo que te deja informar el valor_original tal cual estaba.
  • El guion no es un ausente para pandas: hay que declararlo.
  • La mediana se calcula sobre las filas que sobreviven, no sobre las 120. Si la sacas antes de descartar te da otro numero.
  • edad_imputada vale 1 solo cuando la edad FALTABA, no cuando era invalida: las invalidas se descartan.

Así tiene que quedar

clientes_limpios.csv (objetivo) · 87 filas, se muestran 5
idnombrecorreoedadciudadfecha_altaedad_imputada
C0001José Pazjose.paz@example.com62Salta2025-02-200
C0002Lucía Peñalucia.pena@example.com48Salta2025-01-050
C0003Santiago Herrerasantiago.herrera@example.com40Salta2024-05-120
C0004José Rodríguezjose.rodriguez@example.com67Paraná2024-08-110
C0005Walter Gutiérrezwalter.gutierrez@example.com34Rosario2026-01-010
clientes_rechazados.csv (objetivo) · 33 filas, se muestran 5
id_origencolumnavalor_originalmotivo
C0013correoines.herrera.example.comrestriccion_violada
C0017edad17fuera_de_rango
C0019edad128fuera_de_rango
C0023edad-5fuera_de_rango
C0026correoines.castro.example.comrestriccion_violada
La trampa de este ejercicio

La mediana para imputar se calcula sobre las filas que sobreviven, no sobre las 120. Si la sacás antes de descartar, te va a dar otro número y todas las edades imputadas van a estar mal. Es el único paso donde el orden de las operaciones cambia el resultado.