---
name: suggest_reexpression
kind: function
lang: py
domain: datascience
version: "1.0.0"
purity: pure
signature: "def suggest_reexpression(stats: dict) -> dict"
description: "Sugiere la re-expresion de la escalera de potencias de Tukey (none/log/log1p/sqrt/square/cube/box-cox/yeo-johnson) que mas simetriza una columna numerica, a partir de su skew y su dominio (ceros/negativos). Pura: razona por reglas, NO ejecuta la transformacion. Devuelve recomendacion + razon legible + alternativas ordenadas."
tags: [statistics, eda, reexpression, transform, skew, tukey, ladder-of-powers, box-cox, yeo-johnson, python]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: ""
imports: []
params:
  - name: stats
    desc: "dict con los estadisticos de una columna numerica (sub-bloque `numeric` de un ColumnProfile del grupo eda, o el ColumnProfile completo). Usa `skew` (obligatorio), y `min`/`zero_pct`/`negative_pct` cuando esten para determinar el dominio. Si recibe un ColumnProfile entero, baja a su clave `numeric`."
output: "dict con `recommended` (nombre de la transformacion o None si falta skew), `ladder_power` (exponente conceptual de la escalera de Tukey: 1.0 raw, 0.5 sqrt, 0.0 log, None para data-driven), `reason` (explicacion legible), `alternatives` (lista ordenada de {transform, ladder_power, reason}), `skew` (el usado) y `note` (vacio en caso normal; mensaje si la entrada es incompleta o el dominio es desconocido). Nunca lanza excepcion."
tested: true
tests: ["test_aproximadamente_simetrica_recomienda_none", "test_positiva_fuerte_todo_positivo_recomienda_log", "test_positiva_moderada_todo_positivo_recomienda_sqrt", "test_positiva_con_ceros_fuerte_recomienda_log1p", "test_positiva_con_negativos_recomienda_yeo_johnson", "test_negativa_fuerte_todo_positivo_recomienda_cube", "test_negativa_moderada_todo_positivo_recomienda_square", "test_dominio_desconocido_recomienda_yeo_johnson_con_nota", "test_acepta_columnprofile_completo_con_numeric_anidado", "test_skew_ausente_devuelve_nota", "test_stats_vacio_devuelve_nota", "test_no_dict_no_lanza", "test_skew_no_numerico_devuelve_nota"]
test_file_path: "python/functions/datascience/suggest_reexpression_test.py"
file_path: "python/functions/datascience/suggest_reexpression.py"
---

## Ejemplo

```python
from datascience import suggest_reexpression

# Columna estrictamente positiva con cola derecha larga -> log.
stats = {"skew": 2.3, "min": 1.0, "zero_pct": 0.0, "negative_pct": 0.0}
out = suggest_reexpression(stats)
out["recommended"]     # -> "log"
out["ladder_power"]    # -> 0.0  (escalon p=0 de la escalera de Tukey)
out["reason"]          # -> "skew = 2.3 (cola derecha..., fuerte) y todos los valores > 0: log comprime..."
[a["transform"] for a in out["alternatives"]]   # -> ["box-cox", "sqrt"]

# Con valores negativos, log/Box-Cox no valen -> Yeo-Johnson.
suggest_reexpression({"skew": 1.8, "min": -4.0, "negative_pct": 20.0})["recommended"]  # -> "yeo-johnson"

# Funciona directo sobre el sub-bloque `numeric` de describe_numeric:
# col["numeric"] = {"skew": ..., "min": ..., "zero_pct": ..., "negative_pct": ...}
suggest_reexpression(col["numeric"])
```

## Cuando usarla

Cuando un EDA ya detecto que una columna numerica esta sesgada (|skew| alto en el
bloque `numeric` de `describe_numeric` / `detect_distribution_type`) y quieres el
siguiente paso de Tukey: que transformacion la simetriza. Cierra el gap entre
"detecto skew" y "sugiere la re-expresion". Util antes de modelar (muchos modelos
asumen ~normalidad o varianza estable) y para enriquecer un reporte EDA con una
recomendacion accionable por columna. NO la uses si solo quieres el valor del skew
(eso ya lo da `describe_numeric`).

## Gotchas

- Es **pura**: NO ejecuta la transformacion, solo decide cual sugerir. Aplicarla es
  trabajo del caller (numpy/scipy/sklearn) si decide seguir la recomendacion.
- Necesita `skew`. Sin el devuelve `recommended=None` + `note` (no lanza).
- El dominio (ceros/negativos) se infiere de `min`, `zero_pct` y `negative_pct`. Si
  ninguno esta presente, el dominio es desconocido y sugiere `yeo-johnson` (opcion
  segura para cualquier rango) con una nota; pasale al menos `min` para una decision
  mas fina (log vs sqrt vs Box-Cox).
- `zero_pct`/`negative_pct` se interpretan como ">0 = hay ceros/negativos"; la escala
  (fraccion 0-1 o porcentaje 0-100) es indiferente para la decision.
- Umbrales: |skew|<0.5 -> `none`; 0.5-1.0 -> moderada; >=1.0 -> fuerte. Son la
  convencion habitual, no una verdad absoluta — un caller puede recomputar con el
  `skew` que se devuelve.
- `log`/`Box-Cox` exigen datos estrictamente positivos; con ceros usa `log1p`; con
  negativos o ceros, `Yeo-Johnson`. La funcion ya aplica estas reglas por ti.
