--- name: describe_numeric kind: function lang: py domain: datascience version: "1.1.0" purity: pure signature: "def describe_numeric(values: list, bins: int = 20) -> dict" description: "Calcula el bloque estadistico fino numeric de un ColumnProfile del grupo eda sobre una MUESTRA de una columna numerica. Descarta None/NaN/no-numericos y devuelve min/max/mean/median/mode/std/variance/cv, percentiles, iqr, skew, kurtosis, outliers, zero_pct, negative_pct, distribution_type, histogram e histogram_clipped (segunda vista del histograma con los outliers recortados a las vallas de Tukey). Reusa detect_distribution_type, detect_outliers y histogram del registry." tags: [eda, statistics, profiling, distribution, histogram, datascience] params: - name: values desc: "Lista de valores crudos de una columna (muestra). Puede contener None, NaN, infinitos y strings no numericos: se descartan antes de calcular. bool se trata como no numerico." - name: bins desc: "Numero de buckets equiespaciados del histograma. Default 20." output: "Dict con las claves exactas del contrato numeric_sub del grupo eda: {min, max, mean, median, mode, std, variance, cv, p1, p5, p25, p50, p75, p95, p99, iqr, skew, kurtosis, n_outliers, outlier_pct, zero_pct, negative_pct, distribution_type, histogram, histogram_clipped}. cv = std/mean (None si mean==0). iqr = p75-p25. mode = valor mas frecuente (menor en empate). histogram = lista de {lo, hi, count} sobre el rango completo min..max. histogram_clipped = misma estructura pero re-binado sobre el rango de vallas de Tukey [p25-1.5*iqr, p75+1.5*iqr] (vista central sin outliers); es [] cuando el recorte no excluye nada (ningun outlier), cuando iqr==0 (columna constante) o cuando el recorte deja la muestra sin dispersion. Si tras limpiar quedan 0 valores: todas las claves None, histogram=[] e histogram_clipped=[]." uses_functions: - detect_distribution_type_py_datascience - detect_outliers_py_datascience - histogram_py_datascience uses_types: [] returns: [] returns_optional: false error_type: "" imports: [numpy, math] tested: true tests: ["test_lista_con_outlier_y_none", "test_lista_vacia_todo_none", "test_cv_none_cuando_mean_cero", "test_iqr_y_percentiles"] test_file_path: "python/functions/datascience/describe_numeric_test.py" file_path: "python/functions/datascience/describe_numeric.py" --- ## Ejemplo ```python import sys, os sys.path.insert(0, os.path.join("python", "functions")) from datascience.describe_numeric import describe_numeric # Muestra de una columna numerica (con un None y un outlier claro): prof = describe_numeric([1, 2, 2, 3, 100, None, 4]) print(prof["min"], prof["max"], prof["median"], prof["mode"]) # 1.0 100.0 2.5 2.0 print(prof["distribution_type"]) # etiqueta de forma (too_few_samples si n < 30) print(prof["histogram"][:2]) # [{'lo': 1.0, 'hi': 5.95, 'count': ...}, ...] ``` ## Cuando usarla - Usala cuando construyas el bloque `numeric` de un `ColumnProfile` del grupo `eda` a partir de una **muestra** de una columna numerica (no la tabla entera). - Cuando necesites de un solo paso percentiles finos (p1..p99), iqr, dispersion (std, variance, cv), forma (skew, kurtosis, distribution_type), outliers por z-score e histograma con bordes. - Antes de decidir transformaciones (log, winsorize, escalado) sobre una columna: el `distribution_type`, `n_outliers` y `skew` orientan la decision. ## Gotchas - Funcion pura, sin I/O. Descarta silenciosamente None, NaN, infinitos, strings y bool (True/False no cuentan como datos numericos). - `distribution_type`, `skew` y `kurtosis` vienen de `detect_distribution_type`, que devuelve `too_few_samples` (y skew/kurtosis None) cuando la muestra limpia tiene **menos de 30 valores**. - Los outliers usan z-score con `std` poblacional y threshold 3.0 (de `detect_outliers`): en muestras muy pequeñas un unico valor extremo puede inflar la `std` y no marcarse como outlier (efecto masking). Para deteccion fiable, pasa una muestra suficientemente grande. - `cv` es `None` cuando `mean == 0` (division indefinida). - `histogram_clipped` NO recalcula media/mediana/std: reutiliza los percentiles ya calculados (`p25`, `p75`, `iqr`) para definir el rango de recorte y solo re-bina la sub-muestra dentro de las vallas. Es aditivo: los consumidores que solo miran `histogram` no se ven afectados. ## Capability growth log - v1.1.0 (2026-07-03) — añade la clave `histogram_clipped`: segunda vista del histograma re-binada sobre las vallas de Tukey [p25-1.5·IQR, p75+1.5·IQR] para leer la masa central cuando una cola larga aplasta la escala. Aditivo (los consumidores de `histogram` no cambian); `[]` cuando el recorte no excluye nada, la columna es constante (iqr==0) o la sub-muestra recortada pierde dispersion. Lo consume el capitulo `num_distr` del motor AutomaticEDA como figura adicional dentro del mismo grupo keep-together de la columna.