Saltar al contenido

Indice / Practicas / EJ-4.3

EJ-4.3 · Seleccion con loc, isin y between

Practica de: 4.4 loc vs iloc 4.5 Filtrar filasDificultad: M

Dos condiciones combinadas sobre el padrón de clientes. La parte interesante no es escribirlas: es explicar por qué de 45 clientes que viven en esas ciudades quedan 24, y qué pasó con los otros 21.

Qué hay que hacer

A partir de clientes_crudos.csv, producir clientes_seleccion.csv: los clientes que viven en Mendoza, Rosario o Salta y tienen entre 25 y 60 años, con cinco columnas y ordenados por id.

ELI5Explicado facil

Es una lista de invitados con dos requisitos: que vivan en una de tres ciudades y que tengan cierta edad. Los dos requisitos a la vez, no uno u otro.

Y hay dos fichas donde la edad está escrita como «treinta» o directamente no está. Esas personas no entran - pero tampoco es que hayan sido rechazadas por edad: es que nadie pudo comprobar el requisito. La diferencia importa cuando alguien pregunta.

Archivos

La cuenta que hay que poder hacer

De 45 a 24
GrupoCuántos
Clientes de Mendoza, Rosario o Salta45
- descartados por edad fuera de 25 a 6019
- descartados porque la edad no es un número2
En la salida24

Si tu archivo tiene 24 filas pero no podés explicar esas dos líneas del medio, el ejercicio no está terminado. El segundo grupo es el que no aparece en ningún lado si no lo contás a propósito.

Cómo saber si te salió

python comparar.py mi_salida.csv clientes_seleccion.csv

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

El contrato de salida

clientes_seleccion.csv · 24 filas

ColumnaTipoQue lleva
idtextoEl id original
nombretextoTAL CUAL viene, sin normalizar
correotextoTAL CUAL viene, sin normalizar
edadenteroLa edad ya convertida a numero, entre 25 y 60
ciudadtextoMendoza, Rosario o Salta

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

Que hacer con cada defecto

DefectoDondeAccionAdonde va
edad no numerica ('treinta') o ausente (vacio, NaN, N/A, null, -)2 de los 45 clientes de esas tres ciudadesNO NO se corrige. to_numeric con coerce los deja ausentes, y un ausente no cumple between: quedan afuerano entran en clientes_seleccion.csv
edad fuera del rango 25 a 6019 de los 45quedan quedan afuera, que es lo que pide el enunciadono entran en clientes_seleccion.csv
nombres con espacios de mas y correos en mayusculas3 de los 24 seleccionadosNO NO se normalizan: se escriben tal cual vienenclientes_seleccion.csv
correos sin arroba2 de los 24 seleccionadosNO NO se valida en este ejercicio: el correo no es una condicionclientes_seleccion.csv
Orden de comprobacion

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

  1. convertir edad a numero con errors='coerce'
  2. armar la mascara de ciudad con isin
  3. armar la mascara de edad con between
  4. combinar las dos con & y parentesis
  5. seleccionar con loc las filas y las columnas

La conversion va primero porque between sobre una columna de texto no compara numeros. Y las dos mascaras se combinan antes de indexar, en una sola operacion de loc: filtrar dos veces seguidas tambien funciona, pero deja de ser una sola seleccion y es donde aparecen los problemas de copias.

Conteos clave

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

filas de entrada120
clientes de las tres ciudades45
clientes_seleccion.csv24
descartados por edad fuera de rango19
descartados por edad ausente o no numerica2
edad minima en la salida25
edad maxima en la salida59
por motivo

Invariantes

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

len(seleccion) == 24
24 + 19 + 2 == 45
seleccion['id'].is_unique
set(seleccion['ciudad']) <= {'Mendoza', 'Rosario', 'Salta'}
seleccion['edad'].between(25, 60).all()
seleccion.notna().all().all()
seleccion['id'].is_monotonic_increasing
PISTASSi te trabas, abri esto
  • between incluye los dos extremos por defecto. Con 25 y 60 escritos asi, un cliente de 25 entra.
  • Los parentesis alrededor de cada condicion no son estilo: & tiene mas precedencia que las comparaciones.
  • Las 2 filas que se caen por la edad ausente no aparecen en ningun lado. Contalas: 24 + 19 + 2 tiene que dar 45.
  • loc acepta la mascara y la lista de columnas en la misma expresion. Es la forma que conviene aprender.

Así tiene que quedar

clientes_seleccion.csv (objetivo) · 24 filas, se muestran 5
idnombrecorreoedadciudad
C0002Lucía Peñalucia.pena@example.com48Salta
C0003Santiago Herrerasantiago.herrera@example.com40Salta
C0005Walter Gutiérrezwalter.gutierrez@example.com34Rosario
C0011Belén Torres BELEN.TORRES@EXAMPLE.COM 55Rosario
C0013Inés Herreraines.herrera.example.com30Rosario
Sí, los nombres salen sin normalizar

En la salida vas a ver gabriela ubeda en minúsculas y un correo en mayúsculas. Está bien: este ejercicio selecciona, no limpia. Los mismos datos, limpiados de verdad, son EJ-5.2.

Hasta hay dos correos sin arroba entre los 24 seleccionados, y también quedan: el correo no es una de las dos condiciones.

La conversión de edad es un paso previo, no el ejercicio

edad llega como texto porque adentro hay una palabra y un guion. El contrato te dice cómo convertirla - pd.to_numeric(..., errors="coerce") - para que no tengas que resolver eso acá.

Lo que sí es del ejercicio es la consecuencia: coerce deja NaN, y un NaN no cumple between ni su contrario. Esas dos filas se caen sin que nada avise, y sos vos quien tiene que contarlas.