Timestamps, Timezones y Groupby
Timestamps: el problema de las fechas en datos reales
Las fechas en datos reales vienen en decenas de formatos: "2024-01-15", "15/01/2024", "Jan 15, 2024", 1705276800 (Unix timestamp). pandas puede parsear muchos de ellos, pero eso no significa que siempre adivine bien.
Hay dos problemas distintos que suelen mezclarse:
- parsing: convertir texto o enteros a fechas
- semantica temporal: decidir que instante del tiempo representa realmente ese dato
El problema mas sutil es el de timezones. Un timestamp sin timezone es ambiguo: no sabes si "2024-01-15 10:00" es hora de Ciudad de Mexico, UTC, o Nueva York. Cuando combinas datos de fuentes distintas sin normalizar a UTC primero, puedes introducir diferencias de horas silenciosas que despues contaminan merges, resamples, ventanas de tiempo o calculos de duracion.
La regla:
Siempre almacena en UTC internamente.
Convierte a timezone local solo para mostrar.
Esa regla existe porque separa dos preguntas que no deberian confundirse:
- “¿cual es el instante real?” -> UTC
- “¿como quiero mostrarselo a una persona?” -> timezone local
Otra distincion clave:
tz_localize()asigna timezone a un timestamp que era naivetz_convert()cambia de una timezone a otra manteniendo el mismo instante real
Confundirlas produce errores muy comunes. Si localizas cuando debias convertir, estas reinterpretando la hora; si conviertes cuando el dato aun no tenia timezone, pandas te dira que falta contexto.
Que conviene decidir al parsear fechas
Antes de llamar pd.to_datetime(), conviene fijarte en cuatro cosas:
- Si todas las filas usan el mismo formato o vienen mezcladas.
- Si el origen ya esta en UTC o en una hora local.
- Si existen valores invalidos que deberian convertirse a
NaT. - Si vas a usar la fecha como columna ordinaria o como indice temporal.
Un buen parseo no solo “evita errores”; tambien prepara el terreno para operaciones posteriores como:
- extraer anio, mes, dia de semana o trimestre con
.dt - ordenar cronologicamente
- calcular diferencias de tiempo
- reagrupar por periodos
- hacer joins temporales
Cuando una fecha queda como object, pierdes todas esas capacidades y ademas es mas facil cometer errores silenciosos.
Groupby: lo que probablemente ya sabes y lo que no
Ya usaste groupby en el curso anterior. Aqui el foco es en entender que groupby no es una sola operacion, sino un patron de tres etapas:
- split: dividir las filas por llave(s)
- apply: ejecutar una operacion dentro de cada grupo
- combine: recombinar resultados
Lo importante es que la etapa del medio puede tener objetivos distintos. Por eso vale la pena separar los tres modos mas comunes y cuando usar cada uno:
| Modo | Metodo | Forma del output | Uso tipico |
|---|---|---|---|
| Agregar | .agg() |
Menos filas (una por grupo) | Calcular estadisticas por grupo |
| Transformar | .transform() |
Mismas filas que el original | Agregar columna con estadistica del grupo |
| Filtrar | .filter() |
Subset de filas originales | Quitar grupos que no cumplen condicion |
La mayoria solo conoce el modo agregar. transform es el que mas se necesita en ciencia de datos y machine learning porque te deja incorporar contexto del grupo sin colapsar el dataset.
Ejemplos mentales:
agg: “quiero una tabla resumen”transform: “quiero nuevas columnas, pero conservar cada observacion”filter: “quiero quedarme solo con grupos suficientemente grandes o interesantes”
Cuando groupby se vuelve especialmente poderoso
groupby se vuelve mucho mas util cuando deja de ser solo “promedio por categoria” y pasa a responder preguntas analiticas como:
- ¿que tan lejos esta cada observacion del promedio de su grupo?
- ¿que porcentaje del total del grupo representa cada fila?
- ¿que grupos tienen suficiente muestra para analizar?
- ¿como cambia una variable dentro de cada cliente, ciudad o periodo?
Ejemplos conceptuales:
# porcentaje del total del grupo
df["share"] = df["ventas"] / df.groupby("region")["ventas"].transform("sum")
# quedarse con grupos de tamano suficiente
df_filtrado = df.groupby("cliente").filter(lambda g: len(g) >= 5)
Estas operaciones son muy comunes en datos reales porque mezclan dos niveles de analisis al mismo tiempo:
- el nivel fila
- el nivel grupo
Justamente ahi es donde transform y filter brillan.
Relacion entre tiempo y groupby
Estos dos temas aparecen juntos por una razon: en analisis real es muy comun agrupar por tiempo o construir grupos despues de extraer componentes temporales.
Por ejemplo:
- ventas por mes
- usuarios por dia de la semana
- promedio de transacciones por hora
- comportamiento por trimestre y por region
Una vez que la columna de fecha esta bien parseada, puedes derivar variables temporales y usarlas como llaves de agrupacion. Si esa columna estaba mal interpretada o con timezone inconsistente, todo el analisis por grupo queda sesgado desde el inicio.