96da9e3015
Cuatro funciones nuevas del grupo eda que nutren el capítulo AGREGACION: - select_groupby_keys (pure): elige categóricas agrupables + numéricas medida desde el TableProfile. - groupby_stats_duckdb (impure): GROUP BY push-down en DuckDB (count/mean/median/std/min/max por grupo). - pivot_table_duckdb (impure): pivot A×B push-down, limitado a top filas/cols para no cortar. - suggest_aggregations_llm (impure): el LLM elige las agregaciones interesantes con fallback determinista. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
5.3 KiB
5.3 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 | |||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| pivot_table_duckdb | function | py | datascience | 1.0.0 | impure | def pivot_table_duckdb(db_path: str, table: str, index: str, columns: str, value: str, agg: str = 'mean', top_rows: int = 10, top_cols: int = 8) -> dict | Pivot table (index x columns -> agg(value)) calculada con push-down SQL en DuckDB (GROUP BY en el motor, sin traer filas a RAM) y recortada a las top_rows filas y top_cols columnas con mas observaciones para que quepa entera en un PDF movil / slide PPTX sin cortarse. Version push-down para tablas grandes de la funcion pura `pivot` (que pivota list[dict] en memoria). |
|
|
false | error_go_core |
|
dict. En exito {status:'ok', index, columns, value, agg, row_labels:[...], col_labels:[...], matrix:..., truncated_rows:bool, truncated_cols:bool, note:str}. matrix tiene len(row_labels) filas y cada fila len(col_labels) celdas (valor agregado o None si la combinacion no existe). truncated_* indica si hubo mas filas/columnas que el top. En error {status:'error', error:str} (no lanza). | true |
|
python/functions/datascience/pivot_table_duckdb_test.py | python/functions/datascience/pivot_table_duckdb.py |
Ejemplo
import duckdb
from datascience import pivot_table_duckdb
# Tabla DuckDB de prueba estilo titanic: sex x pclass -> mean(fare).
db = "/tmp/pivot_demo.duckdb"
con = duckdb.connect(db)
con.execute(
"CREATE TABLE titanic AS SELECT * FROM (VALUES "
"('male',1,211.3),('female',1,151.5),('male',3,7.9),"
"('female',3,16.7),('male',1,52.0),('female',2,41.6)"
") t(sex, pclass, fare)"
)
con.close()
res = pivot_table_duckdb(db, "titanic", index="sex", columns="pclass", value="fare", agg="mean")
print(res["status"]) # ok
print(res["row_labels"]) # ['female', 'male'] (orden por nº de observaciones desc; empate -> etiqueta)
print(res["col_labels"]) # [1, 3, 2] (pclass=1 tiene 3 obs, pclass=3 -> 2, pclass=2 -> 1)
print(res["matrix"]) # [[151.5, 16.7, 41.6], [131.65, 7.9, None]] (male/pclass=2 no existe -> None)
Cuando usarla
Cuando quieres una pivot table (index x columns -> agg(value)) de una tabla
DuckDB con MUCHAS filas y necesitas que el resultado quepa entero en un informe: un
PDF abierto en el movil o un slide PPTX, donde una matriz de 50x30 se cortaria. La
agregacion se hace push-down en el motor (no traes las filas a RAM) y el resultado se
limita a las top_rows x top_cols combinaciones con mas observaciones. Encaja en el
flujo eda para resumir el cruce de dos categoricas (sexo x clase, region x producto)
contra una metrica. Para pivotar un list[dict] ya cargado en memoria usa la funcion
pura pivot_py_datascience; esta es la version push-down sobre disco.
Gotchas
- Funcion impura: lee un archivo DuckDB del disco (read_only, nunca lo modifica).
- Recorta a
top_rowsxtop_colspor numero de observaciones (suma deCOUNT(*)), NO por magnitud del valor agregado. Si habia mas filas/columnas,truncated_rows/truncated_colsquedan en True y esas combinaciones NO aparecen en la matriz. - Las celdas sin datos (combinacion
indexxcolumnsque no existe en la tabla) se rellenan conNone, no con 0: distinguir "cero medido" de "sin observaciones". agg='count'cuenta filas por celda conCOUNT(*)e ignoravalue(puedes pasar cualquier nombre de columna). Para el resto de aggs,valuedebe ser una columna numerica real o la query fallara con{status:'error'}.aggsolo admite mean, sum, count, min, max, median; cualquier otro valor devuelve{status:'error'}sin tocar la base.- Orden de
row_labels/col_labels: por numero de observaciones descendente, con desempate estable por etiqueta. No es orden alfabetico ni el de aparicion. - La query se ejecuta con
sandbox=Falseenduckdb_query_readonly(uso interno confiable: el SQL lo construye esta funcion, no un cliente externo).