Saltar al contenido

Indice / Practicas / EJ-6.5

EJ-6.5 · Panel de sucursal por mes

Practica de: 6.5 pivot_table y reshapeDificultad: M

200 transacciones sueltas, y hay que entregar un panel de 5 sucursales por 7 meses. La parte que decide el resultado no es el pivote: es lo que se descarta antes.

Qué hay que hacer

A partir de transacciones_sucursales.csv, producir:

ELI5Explicado facil

Es armar la planilla del año: sucursales en las filas, meses en las columnas, y en cada casillero cuánto se movió.

El problema es que entre los comprobantes hay uno sin fecha, otro con la fecha ilegible y dos sin importe. Si los metés igual, la planilla sale con una columna de un mes que no existe. Hay que apartarlos primero y anotar cuáles fueron.

Archivos

La trampa: el pivote no valida

Una transacción tiene la fecha escrita literalmente fecha_invalida. Si sacás el mes cortando los primeros 7 caracteres del texto, esa fila produce el «mes» fecha_i, y pivot_table arma una columna con ese nombre sin decir nada.

El panel sale con 8 columnas donde hay 7 meses, y las cuatro sucursales que no tienen ninguna transacción rota reciben un 0 en esa columna - que afirma «no hubo movimiento» sobre un mes que no existe.

Por eso el mes se saca de la fecha ya convertida y validada, nunca del texto crudo.

Cómo saber si te salió

python comparar.py mi_panel.csv panel_sucursal_mes.csv
python comparar.py mi_rechazos.csv rechazos_tx.csv

Antes de arrancar, mirá los datos

transacciones_sucursales.csv (entrada) · 200 filas, se muestran 5
idfechasucursaltipocategoriaimporte
TX00012026-07-25CentroIngresoVentas4441.09
TX00022026-04-17NorteGastoServicios publicos3340.4
TX00032026-06-11CentroGastoMarketing2686.81
TX00042026-03-09CentroIngresoServicios1741.92
TX00052026-04-11CentroIngresoServicios3832.7

El contrato de salida

panel_sucursal_mes.csv · 5 filas

ColumnaTipoQue lleva
sucursaltextoEl nombre de la sucursal
2026-01decimalSuma de importes de ese mes, redondeada a 2 decimales
2026-02decimalIdem
2026-03decimalIdem
2026-04decimalIdem
2026-05decimalIdem
2026-06decimalIdem
2026-07decimalIdem

Orden de las filas: sucursal ascendente. Es unica en el panel. Indice: no se escribe: to_csv(index=False). El indice del pivote se baja con reset_index()

rechazos_tx.csv · 5 filas

ColumnaTipoQue lleva
idtextoEl id de la transaccion descartada
columnatextoEn que columna estaba el problema
valor_originaltextoEl valor tal cual venia
motivotextoUno del vocabulario cerrado del curso

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

Que hacer con cada defecto

DefectoDondeAccionAdonde va
fecha vacia1 fila, TX0045descartar descartarrechazos_tx.csv con motivo ausente
fecha escrita 'fecha_invalida'1 fila, TX0012descartar. descartar. Si se le cortan los primeros 7 caracteres produce el mes 'fecha_i', que el pivote acepta como columnarechazos_tx.csv con motivo fecha_invalida
importe ausente: campo vacio y token N/A2 filas, TX0118 y TX0140descartar descartarrechazos_tx.csv con motivo ausente
tipo escrito 'Ingresso'1 fila, TX0067descartar. descartar. NO se corrige a 'Ingreso': el enunciado no autoriza a adivinar la intencionrechazos_tx.csv con motivo dominio_desconocido
una transaccion de 99.999.999,99 en la sucursal Sur1 filaNO NO se descarta: es un valor absurdo pero no invalido, y este ejercicio no valida rangos. Queda a la vista en el panel, que es justamente para lo que sirve un panelpanel_sucursal_mes.csv
categoria ausente en 1 fila1 filaNO NO afecta: la categoria no participa del panelpanel_sucursal_mes.csv
Orden de comprobacion

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

  1. fecha vacia
  2. fecha invalida
  3. importe ausente
  4. tipo fuera del dominio
  5. recien despues: sacar el mes de la fecha YA VALIDADA y pivotar

El mes se saca de la fecha convertida, nunca del texto crudo. Cortar los primeros 7 caracteres de 'fecha_invalida' da 'fecha_i', y pivot_table arma una columna con ese nombre sin decir nada. Validar antes de pivotar es la unica forma de que el panel tenga exactamente los meses que existen.

Conteos clave

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

filas de entrada200
transacciones validas195
rechazos_tx.csv5
panel_sucursal_mes.csv5
meses del panel7
celdas del panel35
por motivoausente: 3, fecha_invalida: 1, dominio_desconocido: 1

Invariantes

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

len(panel) == 5
len(panel.columns) == 8
len(rechazos) == 5
195 + 5 == 200
panel['sucursal'].is_unique
panel.drop(columns='sucursal').notna().all().all()
abs(panel.drop(columns='sucursal').to_numpy().sum() - validas['importe'].sum()) < 0.01
set(rechazos['motivo']) <= {'ausente', 'fecha_invalida', 'dominio_desconocido'}
PISTASSi te trabas, abri esto
  • Si tu panel sale con 8 meses y uno se llama 'fecha_i', sacaste el mes del texto crudo en vez de la fecha validada.
  • El aggfunc por defecto de pivot_table es 'mean'. Sin declararlo, el panel muestra promedios y los numeros son plausibles igual.
  • reset_index() baja la sucursal del indice a columna, y columns.name = None saca el encabezado extra que deja el pivote.
  • La suma de todas las celdas del panel tiene que dar la suma de los importes validos. Es el assert que atrapa las filas descartadas por claves ausentes.

Así tiene que quedar

panel_sucursal_mes.csv (objetivo) · 5 filas, se muestran 5
sucursal2026-012026-022026-032026-042026-052026-062026-07
Centro12199.046194.2121897.6318818.6419081.2819428.6636855.81
Este11326.5622356.9437122.283164.8817060.4526024.027189.87
Norte13916.9917228.047845.0915774.2224692.556246.8116185.71
Oeste22827.8710431.0529278.1423545.0621254.814040.3912412.12
Sur16317.2432258.9329246.317431.76100012246.2833434.3211379.44
rechazos_tx.csv (objetivo) · 5 filas, se muestran 5
idcolumnavalor_originalmotivo
TX0012fechafecha_invalidafecha_invalida
TX0045fechavacioausente
TX0067tipoIngressodominio_desconocido
TX0118importevacioausente
TX0140importeN/Aausente
El número imposible del panel

La celda de Sur en 2026-05 dice más de 100 millones, cuando el resto del panel se mueve entre 3.000 y 37.000. Sale de una sola transacción de 99.999.999,99.

Y no se descarta: este ejercicio valida la estructura (fecha, importe, tipo), no los rangos. Que quede a la vista no es un defecto del panel: es para lo que sirve un panel. Un número así en una planilla de siete columnas se ve en un segundo; entre 200 filas sueltas, no.

Dos parámetros que hay que escribir siempre

aggfunc="sum", porque el default es "mean" y produce un panel de promedios con números perfectamente creíbles. Y fill_value=0, que acá es correcto porque un hueco significa «esa sucursal no movió nada ese mes» y todos los meses están representados.