Tema 4 · 3 · Ejercicio 2: NYC Taxi (Parquet, particiones, vista y tabla curated)
Presentación del Tema 4: «Ejercicio 2 – NYC Taxi». Duración: 45 a 60 minutos, de los que la carga de datos con el script son 1 o 2. Coste: céntimos (unos 300 MB descargados a CloudShell y subidos a S3; Athena con decenas de MB).
¿Dudas con un script? Todos los scripts de esta carpeta traen su propia ayuda:
./gestionar-nyc-taxi.sh --ayuda(también vale--helpo-h) explica los pasos y las opciones. EsteREADME.mdes el paso a paso de la actividad: tenlo a mano y consúltalo antes de preguntar.
Etiquetas de lo que creas. Este ejercicio no crea recursos propios: trabaja dentro de los de
04.01-creardatalake, que ya llevan las etiquetascurso=G214,universidad=CUNEFyactividad=04.01-creardatalake. Más detalle (cómo etiquetar con la CLI, cómo buscar y qué hacer en una emergencia): README principal, sección «Etiquetas».
Qué vas a hacer
Vas a cargar cinco meses de viajes de los taxis amarillos de Nueva York (ficheros Parquet de unos 60 MB cada uno) en tu Data Lake con un script, crear una tabla particionada por año y mes, una vista con columnas calculadas y una tabla limpia (curated), y después resolver en Athena los ejercicios de la presentación.
Qué se crea en AWS (dentro del stack de 04.01): los ficheros raw/nyc_taxi/year=YYYY/month=MM/yellow_tripdata_YYYY-MM.parquet en tu bucket y, en la base demo_datalake_db, la tabla externa nyc_taxi_yellow_raw, la vista v_nyc_taxi_yellow y la tabla nyc_taxi_yellow_curated (Parquet, con ficheros en athena-results/tables/).
Qué contiene esta carpeta
| Fichero | Para qué sirve | Paso en que se usa |
|---|---|---|
gestionar-nyc-taxi.sh |
Gestor del ejercicio: crear (descarga los datos de NYC Taxi, los sube a S3 y crea tablas y vista), estado (qué hay cargado) y eliminar (borra lo de este ejercicio sin tocar el stack). Sin órdenes abre un menú |
Pasos 2 y 3 y limpieza |
2-athena-nyc-taxi.sql |
El SQL que ejecuta gestionar-nyc-taxi.sh crear (tabla, vista y tabla curated). Léelo: es la base de la presentación |
Paso 3 |
README.md |
Esta guía | - |
Antes de empezar
- Necesitas el Data Lake de 04.01 Crear el Data Lake: el stack
g214-datalake-demoenCREATE_COMPLETE, regióneu-north-1. El script consulta el bucket directamente al stack con la AWS CLI; no lee ningún fichero de la otra carpeta. Si el stack no existe o no está enCREATE_COMPLETEse detiene con un mensaje que dice qué hacer. Antes de empezar comprueba también queawses la versión 2, que tus credenciales son válidas y que tienescurl(owget) para descargar. - No necesitas haber hecho 04.02 Titanic, pero en 04.02 se explica «Cómo leer Data scanned en Athena», que aquí se usa de nuevo (resumen en el paso 7).
- Workgroup
demo-athena-workgroupy basedemo_datalake_dbseleccionados en Athena (arriba a la derecha y panel izquierdo). No marques «Reuse query results».
Cómo llevar los ficheros a CloudShell
- En tu PC, comprime esta carpeta (
04.03-nyctaxi, entera) en un zip y no la descomprimas. - En CloudShell (región
eu-north-1): Actions > Upload file >04.03-nyctaxi.zip. - Descomprime, entra y da permisos:
unzip -o 04.03-nyctaxi.zip && cd 04.03-nyctaxi && chmod -R u+rwX . && chmod +x *.sh
Si ya subiste
g214-materiales.zip(README principal), no necesitas este zip: entra concd ~/g214-materiales/tema4/04.03-nyctaxiy, si algún fichero daPermission denied, ejecuta allíchmod -R u+rwX . && chmod +x *.sh.
Ejecuta el script desde dentro de la carpeta: busca 2-athena-nyc-taxi.sql en la carpeta actual y, si no está, junto al propio script. Si al ejecutarlo ves bad interpreter o errores con \r, el zip ha dejado finales de línea de Windows: sed -i 's/\r$//' *.sh y repite.
Paso a paso
Paso 1 · Averigua tu bucket
BUCKET=$(aws cloudformation describe-stacks --stack-name g214-datalake-demo --region eu-north-1 \
--query "Stacks[0].Outputs[?OutputKey=='S3Bucket'].OutputValue" --output text)
echo "$BUCKET"
Qué verás: g214-datalake-demo-datalakebucket-<letras y números>. (Repite el comando si CloudShell se cierra y vuelves más tarde.)
Paso 2 · Elegir los meses
gestionar-nyc-taxi.sh ya trae por defecto cinco meses de 2025 (MONTHS=("2025-09" "2025-08" "2025-07" "2025-06" "2025-05"), una línea cerca del principio del script, la que empieza por MONTHS=(): son los que usan las consultas de la presentación (year = 2025). No tienes que editar nada. Solo si quieres otros meses (la ciudad de Nueva York publica con unos dos meses de retraso: hay datos de 2024, 2025 y 2026 hasta el mes publicado), lo más fácil es pasárselos al ejecutarlo, sin editar el script:
./gestionar-nyc-taxi.sh crear --meses "2025-09 2025-08"
(formato YYYY-MM, separados por espacios; si algún mes no tiene ese formato, el script se detiene antes de descargar nada). Si prefieres cambiar el valor por defecto, edita esa línea con el editor nano:
nano gestionar-nyc-taxi.sh
Busca la línea MONTHS=(...), cámbiala (por ejemplo, para ir más rápido con solo dos meses, MONTHS=("2025-09" "2025-08")), guarda con Ctrl+O y Enter, y sal con Ctrl+X. O, sin editor, con una sola orden:
sed -i 's/^MONTHS=.*/MONTHS=("2025-09" "2025-08")/' gestionar-nyc-taxi.sh
grep -n '^MONTHS=' gestionar-nyc-taxi.sh
Qué verás: el grep muestra la línea MONTHS= con su número y tus meses. Ojo: si cambias a meses de otro año, las consultas con year = 2025 devolverán 0 filas, y los valores de «Qué debes ver» del paso 6 solo valen con los cinco meses por defecto.
Paso 3 · Cargar los datos
./gestionar-nyc-taxi.sh crear
(Sin crear, ./gestionar-nyc-taxi.sh abre un menú numerado: 1) Crear, 2) Ver estado, 3) Eliminar lo de este ejercicio, 0) Salir. Las órdenes directas son crear, estado, eliminar y ayuda; también valen --create, --status y --delete.)
No pide datos por teclado. Qué hace: por cada mes, descarga yellow_tripdata_YYYY-MM.parquet (unos 60 MB cada uno) de la web oficial de la ciudad de Nueva York a un directorio temporal, comprueba que es un Parquet válido (si la descarga falla, reintenta hasta 3 veces) y lo sube a s3://<tu-bucket>/raw/nyc_taxi/year=YYYY/month=MM/, borrando el fichero local nada más subirlo; después ejecuta 2-athena-nyc-taxi.sql: crea la tabla externa nyc_taxi_yellow_raw (particionada por year y month), registra las particiones con MSCK REPAIR TABLE, crea la vista v_nyc_taxi_yellow (con duración, velocidad y porcentaje de propina), crea la tabla limpia nyc_taxi_yellow_curated y lanza 4 consultas de ejemplo (viajes por mes, percentiles de distancia, velocidad y propina, viajes más caros). Si algo falla (stack inexistente, un mes que aún no está publicado, una sentencia de Athena...) imprime qué ha pasado y qué hacer, sin trazas.
Qué verás: por cada mes, una línea con la URL de descarga y otra con el destino de S3 y la línea upload: ...; después Preparando SQL... y 10 pares Athena: ... / OK (<identificador>); al final Listo. NYC Taxi subido y tablas/vistas creadas en Athena. Tarda 1 o 2 minutos (57 segundos con 2 meses, 1 min 17 s con 5, medido con la versión anterior del script). Igual que en el Titanic, no imprime los resultados de las consultas de ejemplo.
Si repites el script: es seguro. Vuelve a descargar y subir los meses (nueva versión de cada fichero), y recrea la tabla, la vista y la curated. Si lo repites con otros meses, los de ejecuciones anteriores siguen en S3 y en las tablas (las particiones se acumulan). Los .parquet no quedan en tu disco: no hay nada que borrar en CloudShell.
Ver qué hay cargado: ./gestionar-nyc-taxi.sh estado muestra el estado del stack, los ficheros de raw/nyc_taxi/ con su tamaño, si existen el workgroup y la base, cuáles de las tres tablas existen y cuántas particiones tiene nyc_taxi_yellow_raw. No cambia nada.
Paso 4 · Verificar S3 y particiones
aws s3 ls "s3://$BUCKET/raw/nyc_taxi/" --recursive --human-readable --region eu-north-1
Qué verás: un fichero por mes, dentro de carpetas year=2025/month=09/, de decenas de MB cada uno.
En Athena (base demo_datalake_db):
SHOW PARTITIONS demo_datalake_db.nyc_taxi_yellow_raw;
SELECT * FROM demo_datalake_db.nyc_taxi_yellow_raw LIMIT 10;
Qué verás: una partición por mes cargado (year=2025/month=09, etc.) y 10 viajes con sus columnas y year/month al final (algunas celdas salen vacías: passenger_count, ratecodeid y airport_fee son NULL en los viajes con payment_type 0). Si añades meses después, ejecuta MSCK REPAIR TABLE demo_datalake_db.nyc_taxi_yellow_raw; para registrarlos; si una tabla que sí tiene datos devuelve 0 filas, casi siempre es que faltan particiones por registrar.
Cuidado con SELECT *. Aunque lleve LIMIT 10, Athena lee en paralelo antes de cortar: con los 5 meses por defecto, el Data scanned de LIMIT 10 no es estable: lo medimos entre 2,6 y 9,7 MB con SELECT * y entre 17,7 y 35,6 MB con WHERE passenger_count > 0, según la ejecución (de unos 3 a unos 35 MB en total), y por eso no sirve para medir. Sin LIMIT sí sale siempre lo mismo: unos 350 MB (350.090.799 B); con más meses cargados todo crece. Y sin LIMIT Athena guarda todas las filas como un CSV de varios GB en s3://<tu-bucket>/athena-results/<id>.csv (3,0 GiB con 20,6 millones de filas, en unos 2 minutos), y la consola solo pinta las primeras. Hazlo una vez para ver el efecto y bórralo después: busca el fichero con aws s3 ls "s3://$BUCKET/athena-results/" --human-readable y bórralo con aws s3 rm "s3://$BUCKET/athena-results/<id>.csv" (el bucket está versionado: queda una versión antigua hasta que borres el stack).
Paso 5 · Las tres tablas
nyc_taxi_yellow_raw: los datos tal como llegaron (zona raw). No se modifica.v_nyc_taxi_yellow: una vista; no ocupa espacio, calculaduration_min,mphytip_rateal vuelo y renombra las fechas apickup_tsydropoff_ts.nyc_taxi_yellow_curated: tabla en Parquet creada desde la vista con filtros (trip_distance > 0,fare_amount >= 0; descarta un 9 % de los viajes: 18,8 millones de 20,6 con los 5 meses por defecto). No filtra los importes absurdos: el viaje más caro de algunos meses supera los 300.000 USD (un error de registro; ejercicio 7). Los ficheros de esta tabla también están bajoathena-results/tables/(mismo comportamiento que en el Titanic).
Ahora haz los ejercicios de la presentación en Athena. Intenta resolverlos tú antes de mirar la tabla del paso 6.
Paso 6 · Qué debes ver en los ejercicios 2 a 7 y el extra
Para comprobar tus resultados con los cinco meses de 2025 por defecto (2025-05 a 2025-09; todas las cifras de esta tabla son de esos cinco meses, y con otros meses cambian):
| Ejercicio | Qué debes ver |
|---|---|
| 2 · viajes por mes (70) | 2025-05 4.591.845; 2025-06 4.322.960; 2025-07 3.898.963; 2025-08 3.574.091; 2025-09 4.251.015. Data scanned 0 B (solo metadatos) |
| 3 · duración media (71) | Decimales largos (17.911712024252516); con ROUND(AVG(duration_min), 2): 17,91 / 17,41 / 17,10 / 17,28 / 18,59. La raw tiene duraciones negativas (hasta -681 min) y de hasta 11.295 min |
| 4 · propinas por método de pago (72) | payment_type: 0 = Flex Fare, 1 = tarjeta de crédito, 2 = efectivo, 3 = sin cargo, 4 = disputa, 5 = desconocido, 6 = viaje anulado. Con ROUND(AVG(tip_rate) * 100, 2): tarjeta (1) 14,24 %; Flex Fare (0) 0,80 %; efectivo (2) 0,0 %: la propina en efectivo no se registra. tip_rate es una fracción (0,1424), no un porcentaje |
| 5 · tasa de aeropuerto mayor de 5 USD (73) | Solo hay filas desde 2025-05, cuando la tasa subió a 6,75 USD: 1.882 / 2.087 / 1.427 / 1.339 / 1.490 viajes (mayo a septiembre). Con meses de 2024 no sale nada |
| 6 · total facturado (74) | Notación científica (1.2148917115003005E8); ROUND no la quita, CAST(SUM(total_amount) AS DECIMAL(15,2)) sí: 121.489.171,15 / 116.050.555,08 / 102.892.243,72 / 93.311.611,67 / 116.020.613,40 |
| 7 · viaje más caro (75) | Importes absurdos: 1.614,29 (mayo); 325.528,45 (junio); 5.297,87; 2.123,44; 323.820,17 (septiembre). La mediana es de unos 22 USD: son errores de registro que la curated no filtra |
| Extra · día de la semana (76) | 7 filas (1 = lunes ... 7 = domingo). Con ROUND(AVG(tip_rate) * 100, 2), el martes tiene el mayor porcentaje de propina (9,81 %) y el domingo el menor (8,13 %); el viernes y el sábado también bajan. Es un patrón del dato, no una causa probada |
Paso 7 · Mide lo que escaneas (recordatorio)
Tras cada consulta, anota Run time y Data scanned (en los resultados de Athena o en Recent queries). Data scanned es lo que Athena leyó de S3 y lo que se factura (5 USD por TB, mínimo 10 MB por consulta). Compara solo cambiando una cosa cada vez, no marques «Reuse query results» (saldría 0 bytes), no uses COUNT(*) sobre Parquet (0 B, solo metadatos) y no mides con LIMIT (no es estable): usa SUM o AVG. La explicación completa está en 04.02, «Cómo leer Data scanned en Athena».
Paso 8 · (Opcional) Panel Streamlit
Si creaste el stack con la instancia EC2 (el valor por defecto), ya puedes ver estos datos en un panel web: 04.07 Panel Streamlit y seguridad.
Errores frecuentes
| Qué ves | Causa | Solución |
|---|---|---|
El stack g214-datalake-demo no existe en eu-north-1 al lanzar ./gestionar-nyc-taxi.sh crear |
El stack no existe o se creó en otra región (el script busca en eu-north-1) |
Comprueba en CloudFormation (región Estocolmo) que existe; si no, vuelve a 04.01 |
No encuentro 2-athena-nyc-taxi.sql |
Estás fuera de la carpeta y el fichero no está junto al script | cd 04.03-nyctaxi y repite |
El mes YYYY-MM aún no está publicado (error 403 o 404) |
Ese mes aún no lo ha publicado la ciudad de Nueva York | Usa meses más antiguos: ./gestionar-nyc-taxi.sh crear --meses "2025-09 2025-08" (los meses anteriores del bucle ya se han subido) |
No he podido descargar ... o no es un Parquet válido |
Red con filtro web o corte de conexión (a veces el filtro devuelve una página de error en vez del fichero) | Repite crear; si persiste, hazlo desde CloudShell |
| Una tabla NYC devuelve 0 filas | Faltan particiones por registrar, o consultas un año/mes no cargado | MSCK REPAIR TABLE demo_datalake_db.nyc_taxi_yellow_raw; y SHOW PARTITIONS |
Una consulta SELECT * sin LIMIT tarda minutos y la consola no pinta todo |
Athena guarda todas las filas como un CSV de varios GB en athena-results/ |
Es lo esperado en la presentación; borra ese fichero después (paso 4) |
Permission denied al ejecutar el script |
El zip creado en Windows no guarda el permiso de ejecución | chmod +x *.sh, o bash ./gestionar-nyc-taxi.sh crear |
bad interpreter o $'\r': command not found |
El zip creado en Windows ha dejado finales de línea de Windows (CRLF) | sed -i 's/\r$//' *.sh y repite |
MALFORMED_QUERY / Only one sql statement is allowed al pegar un .sql |
Hay un comentario -- ... detrás de un ; en la misma línea |
Pon el comentario en la línea de encima o bórralo; ejecuta de una en una |
Limpieza
Solo lo de esta actividad, en este orden (el stack NO se borra aquí: se borra al final del Tema 4 desde 04.01, y debe ser lo último). Ojo: 04.06 y 04.07 usan las tablas y los datos de NYC; si vas a hacerlas, no borres nada de aquí todavía.
- Con el script, desde esta carpeta:
./gestionar-nyc-taxi.sh eliminar
(o la opción 3 del menú). Lista lo que ha creado el ejercicio y te pide confirmar con s (--si para no preguntar). Borra: las tablas nyc_taxi_yellow_curated (con sus ficheros Parquet de athena-results/tables/) y nyc_taxi_yellow_raw, la vista v_nyc_taxi_yellow y los datos de raw/nyc_taxi/ (todas las versiones de los ficheros). Al final verifica y lista lo que quede. No toca el stack, ni las tablas de la actividad 04.06 (nyc_taxi_csv, viajes_compacto, que tienen su propia limpieza), ni nada de otros ejercicios. Si no hay nada, lo dice y termina bien: se puede repetir. Para ver antes qué hay: ./gestionar-nyc-taxi.sh estado.
2. Borra el CSV gigante de resultados si hiciste el SELECT * sin LIMIT del paso 4 (aws s3 rm "s3://$BUCKET/athena-results/<id>.csv"): el script no lo conoce porque lo crea Athena con un identificador al azar.
3. Si vas a borrar el stack, no hace falta nada de esto: todo se va con él. (El script ya no deja ficheros descargados en CloudShell; si vienes de una versión antigua, rm -rf /tmp/cunef_nyc_taxi.)
Cómo sabes que has terminado
- [ ]
aws glue get-tables --database-name demo_datalake_db --region eu-north-1 --query "TableList[].Name"listanyc_taxi_yellow_raw,v_nyc_taxi_yellowynyc_taxi_yellow_curated(y./gestionar-nyc-taxi.sh estadodice que el script ya ha hecho su trabajo). - [ ]
SHOW PARTITIONSmuestra una partición por mes cargado. - [ ] Has ejecutado y entendido las consultas de la presentación y tus cifras coinciden con las del paso 6.
- [ ] Sabes decir qué método de pago deja más propina (la tarjeta) y por qué ese dato engaña (el efectivo no registra la propina).
Anterior: 04.02 Titanic · Siguiente: 04.04 Calidad del aire de Madrid