Metadata-Version: 2.4
Name: estefano-arsenal
Version: 0.1.0
Summary: Funciones reutilizables de limpieza, KPIs, estadística y visualización, extraídas de proyectos reales de Análisis de Datos.
Author: Estefano Gonzalez Bravo
License: MIT
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: pandas>=1.5
Requires-Dist: numpy>=1.23
Requires-Dist: scipy>=1.9
Requires-Dist: statsmodels>=0.13
Requires-Dist: matplotlib>=3.6
Requires-Dist: seaborn>=0.12
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Dynamic: license-file

# estefano-arsenal

Funciones reutilizables de limpieza, KPIs financieros, estadística y visualización, extraídas y generalizadas de proyectos reales de Análisis de Datos (bootcamp TripleTen — Sprints 5 a 12).

```bash
pip install estefano-arsenal
```

---

## 📦 Contenido

| Módulo | Funciones |
|---|---|
| [`limpieza`](#-limpieza) | `limpiar_df`, `verificar_df`, `merge_seguro` |
| [`kpis`](#-kpis) | `calcular_revenue`, `calcular_profit`, `calcular_roi`, `ticket_promedio` |
| [`estadistica`](#-estadistica) | `cramers_v`, `ab_test_proporciones`, `ab_test_medias` |
| [`visualizacion`](#-visualizacion) | `heatmap_correlacion`, `boxplot_ab`, `barplot_conversion` |

Todas las funciones son **agnósticas al dataset**: los nombres de columna se pasan como parámetros, nunca se asumen fijos. Puedes usarlas con cualquier DataFrame de Pandas, sin importar el proyecto.

```python
import arsenal as ar
# o, si prefieres importar cada función por separado:
from arsenal import limpiar_df, calcular_profit, ab_test_medias, boxplot_ab
```

---

## 🧹 limpieza

### `limpiar_df(df, cols_fecha=None, cols_categoricas=None, cols_fillna=None, snake_case=True)`

Pipeline estándar de limpieza: snake_case en columnas + conversión de fechas + normalización de texto + imputación de nulos.

```python
orders = ar.limpiar_df(
    orders,
    cols_fecha=["fecha_hora_pedido"],
    cols_categoricas=["nombre_producto", "categoria_producto"],
    cols_fillna={"dispositivo": "desconocido"},
)
```

### `verificar_df(df, nombre="DataFrame", verbose=True)`

Imprime (y retorna) un resumen de QA: dimensiones, nulos por columna y duplicados.

```python
ar.verificar_df(orders, nombre="orders_clean")
# ========================================
#   QA: orders_clean
# ========================================
#   Dimensiones: (5000, 8)
#   Nulos totales: 0
#   ✅ Sin nulos
#   Duplicados: 0
```

### `merge_seguro(df_izq, df_der, on, how="left", normalizar_texto=True)`

Merge sin columnas duplicadas `_x`/`_y`, con normalización automática (lower + strip) de la llave de cruce para evitar 0 coincidencias por diferencias de capitalización.

```python
orders = ar.merge_seguro(orders, catalog, on="nombre_producto")
```

---

## 💹 kpis

### `calcular_revenue(df, col_monto="monto_total")`

Suma total de ventas.

```python
revenue = ar.calcular_revenue(orders)
```

### `calcular_profit(df_orders, col_monto="monto_total", col_cantidad="cantidad", col_costo_unitario="costo_unitario", df_marketing=None, col_gasto_marketing="gasto", devolver_detalle=False)`

Revenue − Costo de productos − Gasto en marketing.

```python
profit = ar.calcular_profit(orders, df_marketing=marketing)

# Con desglose completo:
detalle = ar.calcular_profit(orders, df_marketing=marketing, devolver_detalle=True)
# {'revenue': ..., 'costo_total_productos': ..., 'inversion_marketing': ..., 'profit': ...}
```

### `calcular_roi(profit, inversion_marketing)`

ROI % = (Profit / Inversión en marketing) × 100.

```python
roi = ar.calcular_roi(profit=detalle["profit"], inversion_marketing=detalle["inversion_marketing"])
```

### `ticket_promedio(df, col_id_pedido="id_pedido", col_monto="monto_total")`

Ticket promedio agrupando por orden (no por línea de producto).

```python
ticket = ar.ticket_promedio(orders)
```

---

## 🧪 estadistica

### `cramers_v(df, col_1, col_2)`

Fuerza de asociación entre dos variables categóricas (0 a 1).

```python
v = ar.cramers_v(df_retail, "tipo_dispositivo", "region")
```

### `ab_test_proporciones(df, col_grupo, col_conversion, grupo_control, grupo_tratamiento, alpha=0.05)`

Z-test de proporciones para comparar tasas de conversión entre dos grupos.

```python
resultado = ar.ab_test_proporciones(
    experimento, col_grupo="variante", col_conversion="convirtio",
    grupo_control="control", grupo_tratamiento="tratamiento",
)
print(resultado["conclusion"])
# Se rechaza H0 (p=0.0021 < 0.05). Existe una diferencia estadísticamente
# significativa: tratamiento convierte +4.30 pp vs. control.
```

### `ab_test_medias(df, col_grupo, col_valor, grupo_control, grupo_tratamiento, alpha=0.05, equal_var=False)`

T-test de Welch para comparar la media de una variable numérica entre dos grupos.

```python
resultado = ar.ab_test_medias(
    df, col_grupo="landing", col_valor="gasto",
    grupo_control="A", grupo_tratamiento="B",
)
print(resultado["conclusion"])
```

Ambas funciones de A/B testing retornan un `dict` con el estadístico, el `p_value`, las métricas por grupo, un booleano `significativo` y una `conclusion` en texto lista para reportar.

---

## 📉 visualizacion

Todas las funciones retornan un `matplotlib.axes.Axes` (nunca llaman a `plt.show()`), por lo que son componibles en subplots.

### `heatmap_correlacion(df, columnas=None, metodo="pearson", cmap="coolwarm", annot=True, titulo=None, ax=None)`

```python
ar.heatmap_correlacion(df, columnas=["ingreso_anual", "compras_mes", "visitas_mes"])
plt.show()
```

### `boxplot_ab(df, col_grupo, col_valor, orden=None, titulo=None, ax=None, palette=None)`

```python
ar.boxplot_ab(df, col_grupo="landing", col_valor="gasto", orden=["A", "B"])
plt.show()
```

### `barplot_conversion(df, col_grupo, col_conversion, orden=None, titulo=None, ax=None, palette="Blues_d")`

```python
ar.barplot_conversion(df, col_grupo="traffic_source", col_conversion="converted")
plt.show()
```

**Combinando en subplots** (patrón típico de un reporte ejecutivo):

```python
fig, axes = plt.subplots(1, 2, figsize=(12, 5))
ar.boxplot_ab(df, col_grupo="landing", col_valor="gasto", ax=axes[0], titulo="Gasto por versión")
ar.barplot_conversion(df, col_grupo="landing", col_conversion="converted", ax=axes[1], titulo="Conversión por versión")
plt.tight_layout()
plt.show()
```

---

## 🛠️ Desarrollo local

```bash
git clone https://github.com/EstefGlez/estefano-arsenal.git
cd estefano-arsenal
pip install -e ".[dev]"
pytest tests/ -v
```

---

## 📚 Origen del código

Cada función de esta librería fue extraída y generalizada del código real (no solo documentado, sino ejecutado y validado) de los siguientes proyectos del bootcamp de Análisis de Datos de TripleTen:

| Sprint | Proyecto | Aporta |
|---|---|---|
| S5 | Movilidad urbana LATAM | Normalización snake_case, merges |
| S7 | Segmentación ConnectaTel | Flags, imputación, merge left |
| S8 | Comportamiento NovaRetail+ | `cramers_v`, `pd.cut`, heatmap de correlación |
| S9 | Pruebas A/B Landing Page | `ab_test_proporciones`, `ab_test_medias`, boxplot/barplot A/B |
| S12 | RappiPlus (proyecto final) | KPIs financieros, `merge_seguro`, `verificar_df` |

Ver el portafolio completo en [Estefano-Gonzalez-Data-Analytics-Portfolio](https://github.com/EstefGlez/Estefano-Gonzalez-Data-Analytics-Portfolio).

---

## 📄 Licencia

MIT — ver [LICENSE](LICENSE).

---

**Autor:** Estefano González Bravo — Sistemas de Ingeniería y Analista de Datos
