Indice / Practicas / EJ-5.6
EJ-5.6 · Deduplicar, validar rango e imputar
Los tres problemas de la unidad en un solo archivo de 50 libros: una clave repetida, valores imposibles y campos vacíos. Cada uno pide una decisión distinta, y una de las tres no es descartar.
Qué hay que hacer
A partir de libros_catalogo.csv, producir:
libros_unicos.csv- el catálogo usable, con una fila por ISBN y sin ningún campo vacío.libros_rechazados.csv- una fila por libro descartado, con la columna, el valor original y el motivo.
ELI5Explicado facil
Estás ordenando la biblioteca y encontrás tres clases de problema:
- Dos libros distintos con el mismo código de barras. No hay forma de saber cuál es el que corresponde: los dos van al cajón de dudosos.
- Un libro que dice haber sido publicado en 2199. Imposible: afuera.
- Un libro sin precio. Ese sí se puede resolver: le ponés lo que cuesta un libro típico de la estantería, y anotás en la ficha que el precio lo pusiste vos.
Lo último es la parte que se olvida. Si no queda anotado, en tres meses nadie distingue el precio real del inventado.
Archivos
- Entrada ·
libros_catalogo.csv - Objetivo ·
libros_unicos.csv - Objetivo ·
libros_rechazados.csv - Herramienta ·
comparar.py
Las tres decisiones
| Qué pasa | Qué se hace | Por qué |
|---|---|---|
| ISBN repetido con títulos distintos | Descartar las dos filas | No hay ninguna columna que diga cuál es la buena |
| Autor vacío | Descartar | Un nombre no se puede estimar del resto del catálogo |
| Año 2199 · precio −5 | Descartar | Son imposibles; el valor real se perdió |
| Año vacío · precio vacío | Imputar y marcarlo | Falta el dato, pero hay una estimación defendible |
Por qué acá se descartan las dos copias y en EJ-5.5 no
En EJ-5.5 el catálogo tenía una columna actualizado, y
las dos filas repetidas eran la misma cosa en dos momentos: quedarse
con la más reciente es una decisión que se puede defender.
Acá no hay fecha, y las dos filas del ISBN 978-1000-001 tienen
títulos y autores diferentes. No son dos versiones: son dos libros a
los que alguien les puso el mismo código. Elegir cualquiera de las dos sería inventar
un criterio que los datos no tienen.
La misma operación, distinta política, porque los datos son distintos. Esa es la idea que vale más que la sintaxis.
Cómo saber si te salió
python comparar.py mi_unicos.csv libros_unicos.csv
python comparar.py mi_rechazados.csv libros_rechazados.csv
Antes de arrancar, mirá los datos
| isbn | titulo | autor | anio | precio |
|---|---|---|---|---|
| 978-1000-001 | Algoritmos vol. 1 | Ximena Molina | 2003 | 57.24 |
| 978-8695-002 | Bases de datos vol. 1 | Guadalupe Gutiérrez | 2016 | 73.18 |
| 978-7073-003 | Redes vol. 1 | Nahuel Vega | 2007 | 47.34 |
| 978-7146-004 | Sistemas operativos vol. 1 | Olivia Ríos | 2025 | 36.31 |
| 978-3259-005 | Compiladores vol. 1 | Delfina Molina | 2006 | 81.58 |
El contrato de salida
libros_unicos.csv · 45 filas
| Columna | Tipo | Que lleva |
|---|---|---|
isbn | texto | La clave del libro, unica en la salida |
titulo | texto | Sin espacios en los extremos |
autor | texto | Sin espacios en los extremos. Nunca vacio |
anio | entero | Entre 1900 y 2026. Los ausentes vienen imputados |
precio | decimal | Mayor que 0, redondeado a 2 decimales. Los ausentes vienen imputados |
anio_imputado | entero | 1 si el anio lo pusimos nosotros, 0 si venia en el archivo |
precio_imputado | entero | 1 si el precio lo pusimos nosotros, 0 si venia en el archivo |
libros_rechazados.csv · 5 filas
| Columna | Tipo | Que lleva |
|---|---|---|
fila_origen | entero | Posicion de la fila en el archivo de entrada, empezando en 0 |
isbn_origen | texto | El ISBN de la fila descartada. NO es unico: el duplicado aparece dos veces |
columna | texto | En que columna estaba el problema |
valor_original | texto | El valor tal cual venia en el archivo |
motivo | texto | Uno del vocabulario cerrado del curso |
Que hacer con cada defecto
| Defecto | Donde | Accion | Adonde va |
|---|---|---|---|
| ISBN 978-1000-001 aparece dos veces, con titulo y autor DISTINTOS | 2 filas, la 0 y la 33 | descartar descartar LAS DOS. No hay ninguna columna que diga cual es la buena: son dos libros distintos con el mismo codigo, no dos versiones del mismo | libros_rechazados.csv con motivo duplicado |
| autor vacio | 1 fila, la 40 (ISBN 978-6834-041) | descartar. descartar. Un autor no se puede imputar: no hay de donde sacarlo | libros_rechazados.csv con motivo ausente |
| anio = 2199, fuera del rango 1900 a 2026 | 1 fila, la 19 (ISBN 978-3226-020) | descartar descartar | libros_rechazados.csv con motivo fuera_de_rango |
| precio = -5.0, que no puede ser | 1 fila, la 12 (ISBN 978-4612-013) | descartar descartar | libros_rechazados.csv con motivo fuera_de_rango |
| anio vacio | 1 fila, ISBN 978-8634-027 | imputar imputar con la mediana entera de los anios de las filas que sobreviven (da 2011) | libros_unicos.csv con anio_imputado = 1 |
| precio vacio y precio con el token NaN | 2 filas, ISBN 978-2045-006 y 978-4222-048 | imputar imputar con la mediana de los precios de las filas que sobreviven, redondeada a 2 decimales (da 52.83) | libros_unicos.csv con precio_imputado = 1 |
Una fila puede tener mas de un problema. Se informa solo el primero de esta lista:
- ISBN repetido
- autor vacio
- anio fuera de rango
- precio fuera de rango
Se informa SOLO el primer motivo de la lista, para que cada fila descartada aparezca una sola vez y valga unicos + rechazados = 50. Y las imputaciones van DESPUES de toda la lista: se imputa sobre lo que quedo, no sobre lo que se va a tirar.
Conteos clave
| filas de entrada | 50 |
|---|---|
| libros_unicos.csv | 45 |
| libros_rechazados.csv | 5 |
| anios imputados | 1 |
| precios imputados | 2 |
| mediana de anio usada | 2011 |
| mediana de precio usada | 52.83 |
| por motivo | duplicado: 2, fuera_de_rango: 2, ausente: 1 |
Invariantes
Comprobaciones que tu resultado tiene que cumplir. Corrilas vos mismo antes de comparar los archivos:
len(unicos) + len(rechazados) == 50
unicos['isbn'].is_unique
unicos['anio'].between(1900, 2026).all()
(unicos['precio'] > 0).all()
(unicos['autor'].str.strip() != '').all()
unicos.notna().all().all()
int(unicos['anio_imputado'].sum()) == 1
int(unicos['precio_imputado'].sum()) == 2
rechazados['fila_origen'].is_unique
int((rechazados['motivo'] == 'duplicado').sum()) == 2
PISTASSi te trabas, abri esto
- duplicated(keep=False) marca TODAS las filas del grupo, no solo las repeticiones. Es lo que hace falta cuando se descartan todas.
- Las dos medianas se calculan sobre las filas que sobreviven. Calculadas sobre las 50 dan 2008 y 55.04, y entonces las tres imputaciones quedan mal.
- El autor no se imputa y el anio si. La diferencia no es tecnica: un anio faltante se estima con el resto del catalogo, un nombre no se puede inventar.
- isbn_origen NO es unico en el archivo de rechazos: el duplicado aparece dos veces. Por eso el orden lo fija fila_origen.
Así tiene que quedar
| isbn | titulo | autor | anio | precio | anio_imputado | precio_imputado |
|---|---|---|---|---|---|---|
| 978-1183-007 | Álgebra lineal vol. 1 | Nahuel Silva | 2004 | 71.97 | 0 | 0 |
| 978-1251-028 | Aprendizaje automático vol. 3 | Javier Ibarra | 1999 | 63.86 | 0 | 0 |
| 978-1309-037 | Álgebra lineal vol. 4 | Santiago Cabrera | 2018 | 16.14 | 0 | 0 |
| 978-2002-019 | Ingeniería de software vol. 2 | Delfina Núñez | 1998 | 52.83 | 0 | 0 |
| 978-2045-006 | Estadística vol. 1 | Horacio Sol | 2004 | 52.83 | 0 | 1 |
| fila_origen | isbn_origen | columna | valor_original | motivo |
|---|---|---|---|---|
| 0 | 978-1000-001 | isbn | 978-1000-001 | duplicado |
| 12 | 978-4612-013 | precio | -5.0 | fuera_de_rango |
| 19 | 978-3226-020 | anio | 2199 | fuera_de_rango |
| 33 | 978-1000-001 | isbn | 978-1000-001 | duplicado |
| 40 | 978-6834-041 | autor | vacio | ausente |
Las dos medianas se sacan sobre las 45 filas que sobreviven, no
sobre las 50 de entrada. Calculadas sobre el archivo entero dan 2008 y
55.04; sobre las que quedan dan 2011 y 52.83.
Los dos programas corren, ninguno da error, y las tres imputaciones quedan distintas. Imputar con un número contaminado por las filas que ya sabemos que están mal es meter el error de vuelta por la ventana.
El ISBN duplicado aparece dos veces en ese archivo, así que no es
una columna única y no alcanza para fijar el orden. Por eso el contrato pide
fila_origen: la posición en el archivo de entrada, que sí es única y
además sirve para ir a mirar la fila original.