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>
7.4 KiB
id, name, kind, lang, domain, version, purity, signature, description, tags, uses_functions, uses_types, returns, returns_optional, error_type, imports, example, tested, tests, test_file_path, file_path, params, output
| id | name | kind | lang | domain | version | purity | signature | description | tags | uses_functions | uses_types | returns | returns_optional | error_type | imports | example | tested | tests | test_file_path | file_path | params | output | ||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| select_groupby_keys_py_datascience | select_groupby_keys | function | py | datascience | 1.0.0 | pure | def select_groupby_keys(profile: dict, max_keys: int = 3, max_card: int = 20, max_measures: int = 4) -> dict | Elige deterministicamente las columnas categoricas mas interesantes para GROUP BY, las numericas medida y pares pivote a partir de un TableProfile del grupo eda. Respaldo cuantitativo para el capitulo de agregacion/OLAP de un EDA. Funcion pura, no muta el input, nunca lanza. |
|
false | from datascience import select_groupby_keys profile = { "n_rows": 891, "key_candidates": ["passenger_id"], "columns": [ {"name": "sex", "inferred_type": "categorical", "distinct_count": 2, "unique_pct": 0.002, "null_pct": 0.0, "flags": [], "categorical": {"imbalance": 1.8}, "numeric": None}, {"name": "pclass", "inferred_type": "categorical", "distinct_count": 3, "unique_pct": 0.003, "null_pct": 0.0, "flags": [], "categorical": {"imbalance": 2.5}, "numeric": None}, {"name": "fare", "inferred_type": "numeric", "distinct_count": 200, "unique_pct": 0.2, "null_pct": 0.0, "flags": [], "numeric": {"std": 49.7, "cv": 1.54}, "categorical": None}, ], } select_groupby_keys(profile) # {"group_keys": [{"col": "sex", ...}, {"col": "pclass", ...}], # "measures": ["fare"], # "pivots": [{"index": "sex", "columns": "pclass", "value": "fare"}], # "note": "2 clave(s) de grupo: sex, pclass; 1 medida(s): fare; 1 pivot(s)."} | true |
|
python/functions/datascience/select_groupby_keys_test.py | python/functions/datascience/select_groupby_keys.py |
|
dict con group_keys (list de {col, cardinality, score} ordenada por score desc), measures (list[str] de nombres de columnas numericas ordenadas por dispersion), pivots (list de {index, columns, value}, hasta 2 pares categorica x categorica con la primera measure como valor) y note (str, resumen corto en espanol de lo elegido). Ante profile vacio/None devuelve todas las listas vacias y una note descriptiva; nunca lanza. |
Ejemplo
from datascience import select_groupby_keys
# TableProfile estilo titanic: 2 categoricas buenas, 1 numerica medida,
# 1 id secuencial (descartado) y un key_candidate declarado.
profile = {
"n_rows": 891,
"key_candidates": ["passenger_id"],
"columns": [
{"name": "sex", "inferred_type": "categorical", "distinct_count": 2,
"unique_pct": 0.002, "null_pct": 0.0, "flags": [],
"categorical": {"imbalance": 1.8}, "numeric": None},
{"name": "pclass", "inferred_type": "categorical", "distinct_count": 3,
"unique_pct": 0.003, "null_pct": 0.0, "flags": [],
"categorical": {"imbalance": 2.5}, "numeric": None},
{"name": "fare", "inferred_type": "numeric", "distinct_count": 200,
"unique_pct": 0.2, "null_pct": 0.0, "flags": [],
"numeric": {"std": 49.7, "cv": 1.54}, "categorical": None},
{"name": "passenger_id", "inferred_type": "numeric", "distinct_count": 891,
"unique_pct": 1.0, "null_pct": 0.0, "flags": ["possible_id"],
"numeric": {"std": 257.4, "cv": 0.58}, "categorical": None},
],
}
select_groupby_keys(profile)
# {
# "group_keys": [
# {"col": "sex", "cardinality": 2, "score": 0.5556},
# {"col": "pclass", "cardinality": 3, "score": 0.4},
# ],
# "measures": ["fare"], # passenger_id excluido (id secuencial)
# "pivots": [{"index": "sex", "columns": "pclass", "value": "fare"}],
# "note": "2 clave(s) de grupo: sex, pclass; 1 medida(s): fare; 1 pivot(s).",
# }
Cuando usarla
Cuando hayas perfilado una tabla con el grupo eda (p.ej.
summarize_table_duckdb) y necesites decidir, sin mirar los datos, por qué
columnas merece la pena agrupar (GROUP BY) y qué métricas numéricas agregar:
el respaldo cuantitativo del capítulo de agregación/OLAP de un AutomaticEDA, o
para proponer pivotes en un dashboard. Es la capa de selección sobre el
TableProfile crudo: lee el perfil, ordena candidatos de forma determinista y
no toca los datos.
Notas
Función pura, sin I/O ni dependencias externas (solo stdlib), no muta
profile. Lectura defensiva total (.get, or [], isinstance): un {} o
None produce {"group_keys": [], "measures": [], "pivots": [], "note": ...}
y nunca lanza.
Criterios de selección (deterministas):
- group_keys — candidatas con
inferred_typeen("categorical","boolean"). Se descartan las que estén enkey_candidates, con flagpossible_id/high_cardinality/constant, condistinct_countfuera de[2, max_card], o all-null (null_pct >= 0.999).score = card_score * balance_score:card_scoremantiene un plateau para cardinalidad moderada (2..12) y decae haciamax_card;balance_score = 1/imbalanceusandocategorical.imbalancesi está, aproximando conmode_pctsi no, o un valor neutro (0.5) en último caso. Devuelve hastamax_keys, ordenadas por score desc (empates por orden de columna). - measures — candidatas con
inferred_typeen("numeric","integer","float"). Se descartan id-like (flagpossible_idyunique_pct >= 0.99) y constantes (numeric.std== 0 o None). Se rankean por dispersión informativa:abs(cv)si está, si noabs(std). Devuelve hastamax_measuresnombres (strings). - pivots — hasta 2 pares
(group_keys[i].col, group_keys[j].col)con i<j y la primera measure como valor. Vacío si hay menos de 2 group_keys.
Caveat de ranking de measures: mezclar cv (adimensional) con std (en
unidades de la columna) cuando una columna carece de cv puede dar órdenes
poco comparables entre columnas; se prefiere cv siempre que esté disponible.