feat(eda): capítulo TIMESERIES del AutomaticEDA (evolución + análisis de serie)
Capítulo nuevo build_timeseries(profile, ctx) -> Chapter|None del motor AutomaticEDA. Cuando la tabla tiene columna de fecha/datetime, grafica la evolución de cada columna numérica por periodo (valor agregado + conteo de filas) y los paneles de descomposición STL y autocorrelación (ACF), con el análisis de la serie: estacionariedad (ADF+KPSS), autocorrelación (Ljung-Box), fuerzas de tendencia/estacionalidad (Hyndman) y la transformación sugerida (retornos o diferencias) para evitar correlaciones espurias. Sin columna temporal devuelve None. Consolida series OHLC casi idénticas en un único gráfico conservando el análisis de cada columna. La serie cruda llega por ctx['timeseries_raw'] (mismo patrón que modelos con raw_numeric); las figuras son perezosas (Figure.make) y el paginador del núcleo garantiza no-corte en PDF y PPTX. CHAPTER_VERSION 1.0.0. Cubre los MUST del diseño (report 2043): MUST-9.1 (línea valor-vs-tiempo + conteo por periodo), MUST-9.2 (paneles STL + ACF), MUST-9.3 (perfil datetime + consolidación OHLC). Funciones nuevas del registry (grupo eda), delegadas a fn-constructor, no inline: - detect_time_column (pure): detecta la columna temporal y las numéricas - profile_datetime (pure): rango/frecuencia/regularidad/huecos de la fecha - resample_timeseries (pure): agrega la serie por periodo + conteo - extract_timeseries_raw (impure): lee la serie cruda ordenada de DuckDB/PG Verificación: 69 tests verdes (capítulo 9 + funciones 28 + núcleo/renderers); golden real sobre seattle-weather (estacional) y aapl (OHLC) con PDF+PPTX sin cortar nada (cols_cortadas=[]). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
---
|
||||
name: detect_time_column
|
||||
kind: function
|
||||
lang: py
|
||||
domain: datascience
|
||||
version: "1.0.0"
|
||||
purity: pure
|
||||
signature: "def detect_time_column(columns: list) -> dict"
|
||||
description: "Detecta, a partir de la lista de ColumnProfile de un TableProfile del grupo eda, cual es la columna de orden temporal y que columnas numericas hay para graficar una serie en el tiempo. Una columna es temporal si inferred_type=='datetime' o semantic_type in {datetime_iso, date_eu}; time_col es la primera temporal en orden. Es la pieza que usa el capitulo TIMESERIES del AutomaticEDA para decidir si aplica. Lectura defensiva dict-no-throw: nunca lanza, siempre devuelve las mismas claves."
|
||||
tags: [eda, timeseries, datetime, profiling, column-detection, automatic-eda, datascience, python]
|
||||
uses_functions: []
|
||||
uses_types: []
|
||||
returns: []
|
||||
returns_optional: false
|
||||
error_type: ""
|
||||
imports: []
|
||||
params:
|
||||
- name: columns
|
||||
desc: "lista de ColumnProfile dict de un TableProfile del grupo eda. Cada elemento suele tener name, inferred_type, semantic_type y numeric. Elementos que no sean dict se ignoran; None/no-lista/vacia -> dict 'no aplica'."
|
||||
output: "dict SIEMPRE con: time_col (str|None, columna temporal elegida = primera temporal), time_semantic (str, semantic_type de la temporal o ''), numeric_cols (list[str], columnas con inferred_type=='numeric' en orden), n_datetime_cols (int), datetime_cols (list[str], todas las temporales en orden de aparicion), reason (str en espanol explicando la eleccion). Nunca lanza excepcion."
|
||||
tested: true
|
||||
tests: ["test_golden_datetime_y_numericas", "test_deteccion_por_semantic_type_date_eu", "test_sin_columna_temporal", "test_columns_none_no_revienta", "test_columns_vacia_no_revienta", "test_columns_no_lista_no_revienta", "test_elementos_basura_se_ignoran", "test_varias_datetime_elige_la_primera"]
|
||||
test_file_path: "python/functions/datascience/detect_time_column_test.py"
|
||||
file_path: "python/functions/datascience/detect_time_column.py"
|
||||
---
|
||||
|
||||
## Ejemplo
|
||||
|
||||
```python
|
||||
from datascience import detect_time_column
|
||||
|
||||
columns = [
|
||||
{"name": "fecha", "inferred_type": "datetime", "semantic_type": "datetime_iso"},
|
||||
{"name": "ventas", "inferred_type": "numeric"},
|
||||
{"name": "unidades", "inferred_type": "numeric"},
|
||||
{"name": "region", "inferred_type": "text"},
|
||||
]
|
||||
res = detect_time_column(columns)
|
||||
res["time_col"] # -> "fecha"
|
||||
res["numeric_cols"] # -> ["ventas", "unidades"]
|
||||
res["n_datetime_cols"] # -> 1
|
||||
|
||||
# Sin columna temporal: el capitulo TIMESERIES no aplica.
|
||||
detect_time_column([{"name": "id", "inferred_type": "numeric"}])["time_col"] # -> None
|
||||
```
|
||||
|
||||
## Cuando usarla
|
||||
|
||||
Cuando el capitulo TIMESERIES del AutomaticEDA recibe un TableProfile y necesita
|
||||
decidir si la tabla admite analisis de serie temporal: si `time_col` es None no
|
||||
hay eje de tiempo y el capitulo se salta; si hay `time_col` y `numeric_cols`,
|
||||
úsalas como eje X (orden cronologico) y series Y. Tambien sirve para enrutar el
|
||||
resto del pipeline (acf_pacf / stl_decompose / adf_kpss_stationarity) sobre las
|
||||
columnas numericas detectadas.
|
||||
|
||||
## Gotchas
|
||||
|
||||
- Es pura y stdlib-only (sin numpy ni DuckDB): segura de llamar en cualquier paso.
|
||||
- `time_col` se elige por ORDEN de aparicion en la lista, no por "mejor candidata".
|
||||
Si hay varias columnas datetime y quieres otra, filtra `datetime_cols` tu mismo.
|
||||
- Solo mira metadatos del perfil (`inferred_type`/`semantic_type`); no parsea ni
|
||||
valida los valores reales de la columna. La calidad de la deteccion depende de
|
||||
que el profiler (summarize_table_duckdb / infer_semantic_type) haya inferido bien.
|
||||
- Las claves del semantic_type son exactamente las del profiler: `datetime_iso`
|
||||
(ISO 8601) y `date_eu` (DD/MM/AAAA). Otros formatos de fecha no se detectan por
|
||||
semantic_type salvo que `inferred_type` ya sea `"datetime"`.
|
||||
- `numeric_cols` se basa en `inferred_type == "numeric"` (no en "integer"/"float");
|
||||
si tu profiler usa otra etiqueta, normalizala antes.
|
||||
Reference in New Issue
Block a user