a69d14d38e
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>
5.6 KiB
5.6 KiB
name, kind, lang, domain, version, purity, signature, description, tags, uses_functions, uses_types, returns, returns_optional, error_type, imports, params, output, tested, tests, test_file_path, file_path
| name | kind | lang | domain | version | purity | signature | description | tags | uses_functions | uses_types | returns | returns_optional | error_type | imports | params | output | tested | tests | test_file_path | file_path | |||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| extract_timeseries_raw | function | py | datascience | 1.0.0 | impure | def extract_timeseries_raw(query_fn, table: str, time_col: str, value_cols: list, max_rows: int = 5000) -> dict | Extrae la serie temporal CRUDA (fechas + una o varias columnas numericas) de una tabla, ordenada cronologicamente, para alimentar el render del capitulo TIMESERIES de AutomaticEDA (linea valor-vs-tiempo + conteo por periodo). Recibe un lector read-only inyectado `query_fn(sql) -> dict` (mismo contrato que duckdb_query_readonly / pg_query / el `_q` de profile_table) y NO abre ninguna conexion por su cuenta. Construye UNA sola query con identificadores escapados, ORDER BY por la columna temporal y LIMIT. Devuelve dict dict-no-throw: t (fechas ISO string), series (lista paralela float|None por columna) y n. El capitulo no toca la BD: recibe esto en ctx['timeseries_raw']. Reutilizable tambien por profile_table en una fase futura. |
|
false | error_go_core |
|
|
dict (nunca lanza). En exito: {'status':'ok','time_col':str,'t':[str,...] (fechas ISO en orden),'series':{col:[float|None,...],...} (paralela a t por value_col, None si el valor no es convertible a float),'n':int}. En error (sin lanzar): {'status':'error','error':str,'time_col':str,'t':[],'series':{},'n':0}. Errores: query_fn None, value_cols vacia, table/time_col vacios, o query_fn devuelve status!='ok' (se propaga su error). | true |
|
python/functions/datascience/extract_timeseries_raw_test.py | python/functions/datascience/extract_timeseries_raw.py |
Ejemplo
import sys, os
sys.path.insert(0, os.path.join("python", "functions"))
from datascience import extract_timeseries_raw
from infra import duckdb_query_readonly
# El lector read-only se inyecta como closure (igual que el `_q` de profile_table).
db = "data/ventas.duckdb"
def _q(sql):
return duckdb_query_readonly(db, sql)
res = extract_timeseries_raw(_q, "ventas_diarias", "fecha", ["importe", "unidades"])
# res == {
# "status": "ok",
# "time_col": "fecha",
# "t": ["2024-01-01", "2024-01-02", ...],
# "series": {"importe": [1234.5, 980.0, ...], "unidades": [12.0, 9.0, ...]},
# "n": 365,
# }
# Se entrega al capitulo TIMESERIES sin que este toque la BD:
ctx = {"timeseries_raw": res}
Cuando usarla
Cuando el capitulo TIMESERIES de AutomaticEDA necesita pintar una serie
valor-vs-tiempo (o conteo por periodo) y NO debe abrir la base de datos por su
cuenta: extraes aqui las fechas + columnas numericas ordenadas y se las pasas en
ctx['timeseries_raw']. Usala tambien siempre que quieras la secuencia cruda
ordenada cronologicamente de una o varias columnas para alimentar otros
contrastes de serie (ADF/KPSS, ACF/PACF, STL) reutilizando un unico lector
read-only inyectado, en vez de hacer N muestreos a mano.
Gotchas
- Impura: lee de la base de datos a traves de
query_fn. No abre conexiones por su cuenta — depende por completo del lector inyectado. Sigue el estilo dict-no-throw del grupoeda: nunca lanza; ante cualquier fallo devuelve{"status":"error","error":...}cont=[],series={},n=0. error_typeen el frontmatter eserror_go_corepor convencion del registry (toda funcion impura debe declararlo y el indexer lo exige), pero el codigo NO lanza esa excepcion: degrada al dict de error. Es metadata, no comportamiento.- No loguear los datos crudos:
t/seriespueden contener datos sensibles (igual que un HAR). No volcar el dict completo a logs ni a telemetria; en trazas usa solony los nombres de columna. - Alineacion por fila:
series[col][i]corresponde at[i]. Un valor no convertible a float se guarda comoNone(no se descarta la fila) para no romper la alineacion temporal. - Orden: el orden cronologico depende del
ORDER BY "time_col"del backend. Sitime_colesta guardada como texto con formato no lexicograficamente ordenable (p.ej.DD/MM/YYYY), el orden no sera el real — normaliza la columna a date/timestamp antes, o pasa una columna ya ordenable. max_rows: con LIMIT, si la tabla superamax_rowsobtienes solo el primer tramo cronologico, no un muestreo uniforme. Subemax_rowssi necesitas el rango completo.