Optimización del Dataset NYC-Train-Trip
20 Retos para dominar la memoria, vectorización y agregaciones avanzadas.
Fase 1: Diagnóstico
1. Inspección Profunda
df.info() miente. Pandas subestima el peso de los objetos. El reto es descubrir la verdad.
train.csv. Compara el uso de RAM reportado por defecto vs memory_usage='deep'.
df.info(memory_usage='deep')
Fase 1: Diagnóstico
2. Downcasting Numérico
¿Por qué usar 64 bits para contar hasta 6 pasajeros? int8 es suficiente.
passenger_count a int8 usando pd.to_numeric.
pd.to_numeric(df['col'], downcast='integer')
Fase 1: Diagnóstico
3. Categoricals
Los strings repetitivos consumen gigabytes. Las categorías guardan índices.
store_and_fwd_flag ('Y'/'N') convirtiéndola a tipo categoría.
df['flag'] = df['flag'].astype('category')
Fase 2: Vectorización
4. Parsing Explícito
Dejar que Pandas "adivine" el formato fecha por fecha es lento. Sé explícito.
to_datetime con y sin format='%Y-%m-%d...'.
pd.to_datetime(col, format='%Y-...')
Fase 2: Vectorización
5. Accessors (.dt)
Extrae componentes de fecha en C, sin loops de Python.
hour y day_name. Encuentra la hora pico de NYC.
df['hour'] = df['datetime'].dt.hour
Fase 2: Vectorización
6. Lógica Vectorizada
apply con if/else es un crimen en Big Data. Usa NumPy.
np.where.
np.where(condicion, 'Valor Si', 'Valor No')
Fase 2: Vectorización
7. Matemáticas Geoespaciales
Trigonometría sobre arrays enteros para calcular distancias reales.
np.sin y np.cos para obtener Km.
c = 2 ⋅ atan2( √a, √(1−a) )
d = R ⋅ c
Fase 3: Código Elegante
8. Filtrado con .query()
Sintaxis tipo SQL, más limpia que los corchetes anidados.
df.query('passenger > 1 and 0 < dist < 100')
Fase 3: Código Elegante
9. Creación (.assign)
Crea columnas al vuelo sin romper la cadena de métodos.
velocidad_kph y ordena descendentemente en un solo bloque.
.assign(vel = lambda x: x.dist / x.time)
.sort_values('vel')
Fase 3: Código Elegante
10. Outliers (.clip)
No borres datos, "tópalos" a límites lógicos.
.clip(lower=60, upper=7200)
Fase 3: Código Elegante
11. Funciones Propias (.pipe)
Inyecta tus propias funciones dentro de una cadena de Pandas.
def etiqueta_trafico(df) y úsala al final de tu cadena.
df.query(...).assign(...).pipe(mi_funcion)
Fase 4: Agregaciones
12. Named Aggregation
Control total sobre los nombres de columnas resultantes.
mean_duration y total_km.
agg(nueva_col=('col_orig', 'func'))
Fase 4: Agregaciones
13. La Magia de .transform
Agrega estadísticas del grupo a cada fila original (Window Function).
avg_duration_by_hour. Cada fila sabe el promedio de su hora.
Fase 4: Agregaciones
14. Filtrado de Grupos
Elimina grupos enteros que no cumplan una condición estadística.
groupby('hour').filter(lambda x: len(x) > 10k)
Fase 4: Agregaciones
15. Binning (qcut)
Convierte variable continua en discreta por cuantiles.
pd.qcut(df['dist'], 4, labels=[...])
Muy Corto]; B --> D[25-50%
Corto]; B --> E[50-75%
Largo]; B --> F[75-100%
Muy Largo]; style B fill:#DA291C,color:white
Fase 5: Series Temporales
16. Resample()
El groupby superpoderoso para índices de tiempo.
df.set_index('ts').resample('D').size()
Fase 5: Series Temporales
17. Rolling Windows
Suaviza el ruido diario para ver la tendencia real.
.rolling(7).mean()
Fase 5: Visualización
18. Scatter con Alpha
Millones de puntos sólidos no dicen nada. La transparencia revela densidad.
alpha=0.1. Busca líneas raras.
Fase 5: Visualización
19. Correlaciones
Entiende qué variables se mueven juntas.
Fase 5: Exportación
20. Formato Parquet
CSV es lento y pierde tipos de datos. Parquet comprime y preserva esquema.
clean.parquet y compara tamaño vs CSV.
df.to_parquet('archivo.parquet')
¡Reto Completado!
Has pasado de Pandas Básico a Ingeniería de Datos Eficiente.