Indice / Practicas / EJ-4.2
EJ-4.2 · Top 20 de marzo con columna derivada
Las 20 ventas más grandes de marzo. El importe no está en el archivo: hay que calcularlo. Y hay una venta de marzo que se va a quedar afuera, a propósito.
Qué hay que hacer
A partir de ventas_mensuales.csv, producir
ventas_marzo_top20.csv: las 20 ventas de marzo con mayor importe,
donde importe = unidades × precio_unitario.
ELI5Explicado facil
Te dan el cuaderno de ventas del trimestre y te piden las 20 ventas más grandes de marzo. El cuaderno anota cuántas unidades y a qué precio, pero nunca el total: eso lo tenés que hacer vos, venta por venta.
Y hay una anotación de marzo escrita con otra letra, en otro formato. Con la regla que estás usando para reconocer marzo, esa se te escapa.
Archivos
- Entrada ·
ventas_mensuales.csv - Objetivo ·
ventas_marzo_top20.csv - Herramienta ·
comparar.py
La limitación que el contrato declara
En esta unidad todavía no vimos fechas. Para quedarte con marzo vas a usar lo que
sí tenés: el texto de la columna empieza con 2026-03.
Funciona para 59 de las 60 ventas de marzo. La que falta tiene la fecha escrita
15/03/2026, y con esa regla no entra. No es un error
tuyo ni un descuido del enunciado: es el límite de la herramienta, está escrito en el
contrato, y es exactamente el problema que resuelve EJ-5.3.
Que el resultado sea reproducible no significa que sea completo. Vale la pena saber la diferencia.
Cómo saber si te salió
python comparar.py mi_salida.csv ventas_marzo_top20.csv
Antes de arrancar, mirá los datos
| fecha | vendedor | producto | unidades | precio_unitario |
|---|---|---|---|---|
| 2026-03-02 | Carlos Ruiz | Auriculares | 1 | 57.24 |
| 2026-03-26 | Carlos Ruiz | Auriculares | 5 | 57.73 |
| 2026-03-31 | Beatriz Molina | Auriculares | 1 | 59.37 |
| 2026-02-09 | Lucía Vega | Webcam | 6 | 45.42 |
| 2026-03-27 | Carlos Ruiz | Laptop | 7 | 914.44 |
El contrato de salida
ventas_marzo_top20.csv · 20 filas
| Columna | Tipo | Que lleva |
|---|---|---|
fila_origen | entero | Posicion de la fila en el archivo de entrada, empezando en 0. Hay que crearla |
fecha | texto | La fecha tal cual viene |
vendedor | texto | Tal cual viene |
producto | texto | Tal cual viene |
unidades | entero | Tal cual viene |
precio_unitario | decimal | Tal cual viene |
importe | decimal | unidades por precio_unitario, redondeado a 2 decimales |
Que hacer con cada defecto
| Defecto | Donde | Accion | Adonde va |
|---|---|---|---|
| la fecha 15/03/2026, que es de marzo pero esta escrita en otro formato | 1 fila, la 120 | NO NO entra. Marzo se identifica por el prefijo '2026-03' del texto, que es la herramienta de esta unidad | queda fuera de ventas_marzo_top20.csv, y es una limitacion conocida que resuelve EJ-5.3 |
| unidades o precio ausentes | 1 fila de marzo | el el importe queda ausente y la fila va al final del orden: no llega al top 20 | queda fuera de ventas_marzo_top20.csv |
| unidades negativas | 2 filas, ninguna de marzo | NO NO se validan en este ejercicio | no afecta a la salida |
| empates de importe en el borde del top 20 | no ocurre en este archivo, pero la regla va igual | desempatar desempatar por fila_origen ascendente | ventas_marzo_top20.csv |
Una fila puede tener mas de un problema. Se informa solo el primero de esta lista:
- agregar fila_origen antes de filtrar nada
- filtrar las fechas que empiezan con 2026-03
- calcular importe y redondearlo
- ordenar por importe descendente y fila_origen ascendente
- quedarse con las primeras 20
fila_origen se agrega ANTES de filtrar: si se agregara despues seria la posicion dentro de marzo y no dentro del archivo, y dejaria de servir para volver a la fila original. Y el redondeo va antes de ordenar, porque dos importes que difieren en el sexto decimal ordenan distinto pero se escriben iguales.
Conteos clave
| filas de entrada | 180 |
|---|---|
| ventas de marzo por prefijo | 59 |
| de esas, con importe calculable | 58 |
| ventas_marzo_top20.csv | 20 |
| importe mas alto | 9885.7 |
| importe mas bajo del top | 894.0 |
| ventas de marzo que quedan fuera del top | 39 |
| por motivo |
Invariantes
Comprobaciones que tu resultado tiene que cumplir. Corrilas vos mismo antes de comparar los archivos:
len(top) == 20
top['fila_origen'].is_unique
top['fecha'].str.startswith('2026-03').all()
top['importe'].is_monotonic_decreasing
top['importe'].notna().all()
(top['importe'] - (top['unidades'] * top['precio_unitario'])).abs().max() < 0.005
list(top.columns) == ['fila_origen', 'fecha', 'vendedor', 'producto', 'unidades', 'precio_unitario', 'importe']
PISTASSi te trabas, abri esto
- str.startswith necesita na=False si la columna tiene ausentes, y esta los tiene: hay 4 fechas vacias.
- assign con lambda te deja calcular el importe y seguir encadenando sin variables intermedias.
- head(20) despues de ordenar hace lo mismo que nlargest, pero nlargest no te deja declarar el desempate.
- fila_origen no viene en el archivo. Sin ella no hay ninguna columna unica, y el top 20 dependeria del algoritmo de ordenamiento el dia que dos importes empaten.
Así tiene que quedar
| fila_origen | fecha | vendedor | producto | unidades | precio_unitario | importe |
|---|---|---|---|---|---|---|
| 60 | 2026-03-13 | Martín Ríos | Laptop | 11 | 898.7 | 9885.7 |
| 113 | 2026-03-16 | Ana Pérez | Laptop | 10 | 910.01 | 9100.1 |
| 29 | 2026-03-30 | Martín Ríos | Laptop | 10 | 887.09 | 8870.9 |
| 4 | 2026-03-27 | Carlos Ruiz | Laptop | 7 | 914.44 | 6401.08 |
| 26 | 2026-03-19 | Diego Sol | Laptop | 4 | 942.62 | 3770.48 |
Uno. fila_origen se agrega antes de filtrar.
Si la agregás después, numera las filas de marzo y no las del archivo, y deja de
servir para volver a la fila original.
Dos. El importe se redondea antes de ordenar. Dos importes que difieren en el sexto decimal ordenan distinto y se escriben iguales: el archivo sale con dos filas en un orden que nadie puede explicar mirándolo.
fila_origen y no nlargest
nlargest(20, "importe") hace el trabajo en una línea, y no te deja
declarar qué pasa si el puesto 20 y el 21 empatan. En este archivo no empatan; en el
del mes que viene, quién sabe.
sort_values([...]).head(20) es una línea más y deja la regla escrita.
Ese es el criterio de todo el curso.