Saltar al contenido

Indice / Practicas / EJ-5.5

EJ-5.5 · Deduplicar por recencia

Practica de: 5.5 DuplicadosDificultad: M

62 filas para 60 productos. Sacar las dos que sobran es fácil; lo difícil es quedarse con la copia correcta, porque el conteo de filas da bien de las dos formas.

Qué hay que hacer

A partir de catalogo_sistema_a.csv, producir catalogo_a_unico.csv: una fila por SKU, conservando de cada producto repetido la versión más reciente según la columna actualizado.

ELI5Explicado facil

Tenés dos fichas del mismo producto. Una dice que sale $695 y es de agosto; la otra dice $31 y es de fin de agosto.

Si te quedás con cualquiera te va a quedar una sola ficha, que es lo que pediste. Pero la mitad de las veces vas a tener el precio viejo, y nadie se va a dar cuenta mirando el total: la cantidad de productos va a ser la correcta igual.

Archivos

La trampa, que no da error

drop_duplicates(subset=["sku"]) a secas se queda con la primera fila de cada SKU, que acá es la vieja. El archivo sale con 60 filas, todos los conteos cierran, ningún assert se rompe… y dos precios están mal.

Este es el error más caro de la unidad justamente porque es invisible en cualquier revisión que solo mire cantidades. La única forma de que keep signifique algo es ordenar antes por la columna que define cuál es la buena.

Cómo saber si te salió

python comparar.py mi_salida.csv catalogo_a_unico.csv

Antes de arrancar, mirá los datos

catalogo_sistema_a.csv (entrada) · 62 filas, se muestran 5
skunombrepreciostockactualizado
SKU001Artículo 001205.25222026-07-23
SKU002Artículo 002695.67842026-08-06
SKU003Artículo 00331.891512026-08-09
SKU004Artículo 004vacio1952026-07-15
SKU005Artículo 005174.261262026-08-07

Buscá SKU002 y SKU007: son los dos que aparecen dos veces, y las dos veces con precios muy distintos.

El contrato de salida

catalogo_a_unico.csv · 60 filas

ColumnaTipoQue lleva
skutextoLa clave del producto, unica en la salida
nombretextoSin espacios en los extremos
preciodecimalRedondeado a 2 decimales. Puede quedar vacio: hay 1 producto sin precio
stockenteroPuede quedar vacio: hay 1 producto con el token NaN
actualizadotextoLa fecha AAAA-MM-DD de la version que sobrevivio

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

Que hacer con cada defecto

DefectoDondeAccionAdonde va
SKU002 aparece dos veces, con precio 695.67 (2026-08-06) y 31.5 (2026-08-20)2 filasconservar conservar la version mas reciente: la del 2026-08-20catalogo_a_unico.csv, con precio 31.5
SKU007 aparece dos veces, con precio 85.34 (2026-07-15) y 88.0 (2026-08-22)2 filasconservar conservar la version mas reciente: la del 2026-08-22catalogo_a_unico.csv, con precio 88.0
empate de fechas entre dos versiones del mismo SKUno ocurre en este archivo, pero la regla tiene que estar igualgana gana la que aparece ultima en el archivo: sort_values(kind='stable') y drop_duplicates(keep='last')catalogo_a_unico.csv
precio vacio1 fila, SKU004NO NO se valida en este ejercicio: la fila se conserva y el precio queda vaciocatalogo_a_unico.csv
stock con el token NaN1 fila, SKU010NO NO se valida en este ejercicio: se convierte a ausente y la fila se conservacatalogo_a_unico.csv
Orden de comprobacion

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

  1. ordenar por actualizado ascendente, con kind='stable'
  2. drop_duplicates(subset=['sku'], keep='last')
  3. ordenar el resultado por sku ascendente

keep='last' significa 'la ultima de la tabla', no 'la mas reciente'. Solo despues de ordenar por fecha las dos cosas coinciden. Y el orden final por sku es del contrato de salida, no del algoritmo: se hace al final, sobre lo que quedo.

Conteos clave

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

filas de entrada62
catalogo_a_unico.csv60
SKU repetidos2
filas eliminadas2
productos sin precio1
productos sin stock1
por motivo

Invariantes

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

len(unico) == 60
unico['sku'].is_unique
len(unico) == pd.read_csv('catalogo_sistema_a.csv')['sku'].nunique()
unico.loc[unico['sku'] == 'SKU002', 'actualizado'].item() == '2026-08-20'
unico.loc[unico['sku'] == 'SKU007', 'actualizado'].item() == '2026-08-22'
int(unico['precio'].isna().sum()) == 1
int(unico['stock'].isna().sum()) == 1
PISTASSi te trabas, abri esto
  • drop_duplicates sin ordenar antes se queda con la primera del archivo, que aca es la version vieja. La cantidad de filas te va a dar bien igual: por eso el error no se ve en ningun conteo.
  • Si ponés actualizado dentro de subset, las dos filas dejan de ser duplicadas y no se elimina ninguna.
  • Un assert de unicidad despues de deduplicar cuesta una linea y convierte un error silencioso en uno ruidoso.
  • El token NaN de la columna stock es texto en el archivo. Que termine como ausente es una decision, no algo que pase solo si leiste como texto.

Así tiene que quedar

catalogo_a_unico.csv (objetivo) · 60 filas, se muestran 5
skunombrepreciostockactualizado
SKU001Artículo 001205.25222026-07-23
SKU002Artículo 00231.5122026-08-20
SKU003Artículo 00331.891512026-08-09
SKU004Artículo 004vacio1952026-07-15
SKU005Artículo 005174.261262026-08-07
La regla de desempate va aunque no haga falta

En este archivo las dos versiones de cada SKU tienen fechas distintas, así que no hay empate. El contrato lo fija igual: si dos versiones comparten la fecha, gana la que aparece última en el archivo, que es lo que se obtiene con sort_values(kind="stable") y keep="last".

Escribir la regla cuando no se necesita es barato. Descubrir que hacía falta cuando el archivo del mes que viene sí tiene un empate, no.

Lo que este ejercicio no hace

Hay un producto sin precio y otro con el token NaN en el stock. Los dos se conservan, con el campo vacío. Este ejercicio deduplica y nada más; validar y decidir qué hacer con los ausentes es EJ-5.6, que además sí produce un archivo de rechazos.