statslibx 0.1.3__py3-none-any.whl → 0.1.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
statslibx/utils.py CHANGED
@@ -6,6 +6,7 @@ import warnings
6
6
  import os
7
7
  from scipy import stats
8
8
  import seaborn as sns
9
+ from pathlib import Path
9
10
 
10
11
 
11
12
  class UtilsStats:
@@ -13,11 +14,15 @@ class UtilsStats:
13
14
  Clase utilitaria para operaciones estadísticas comunes y visualización
14
15
 
15
16
  Esta clase proporciona métodos para validación de datos, análisis estadísticos
16
- básicos y visualización de resultados.
17
+ básicos y visualización de resultados. Ahora con soporte para leer archivos directamente.
17
18
 
18
19
  Examples:
19
20
  ---------
20
21
  >>> utils = UtilsStats()
22
+ >>> # Desde archivo
23
+ >>> data = utils.load_data("datos.csv")
24
+ >>> utils.check_normality(data, column='edad')
25
+ >>> # Desde array
21
26
  >>> data = np.random.normal(0, 1, 100)
22
27
  >>> utils.check_normality(data)
23
28
  >>> utils.plot_distribution(data)
@@ -47,15 +52,11 @@ class UtilsStats:
47
52
  plt.rcParams['lines.linewidth'] = 2
48
53
 
49
54
  def set_plot_backend(self, backend: Literal['matplotlib', 'seaborn', 'plotly']):
50
- """
51
- Establecer el backend de visualización por defecto
52
- """
55
+ """Establecer el backend de visualización por defecto"""
53
56
  self._plot_backend = backend
54
57
 
55
58
  def set_default_figsize(self, figsize: Tuple[int, int]):
56
- """
57
- Establecer el tamaño de figura por defecto
58
- """
59
+ """Establecer el tamaño de figura por defecto"""
59
60
  self._default_figsize = figsize
60
61
  plt.rcParams['figure.figsize'] = [figsize[0], figsize[1]]
61
62
 
@@ -63,18 +64,14 @@ class UtilsStats:
63
64
  fig_format: str = 'png',
64
65
  fig_dpi: int = 300,
65
66
  figures_dir: str = 'figures'):
66
- """
67
- Configurar opciones para guardar figuras
68
- """
67
+ """Configurar opciones para guardar figuras"""
69
68
  self._save_fig = save_fig
70
69
  self._fig_format = fig_format
71
70
  self._fig_dpi = fig_dpi
72
71
  self._figures_dir = figures_dir
73
72
 
74
73
  def _save_figure(self, fig, filename: str, **kwargs):
75
- """
76
- Guardar figura si save_fig está activado
77
- """
74
+ """Guardar figura si save_fig está activado"""
78
75
  if self._save_fig:
79
76
  try:
80
77
  os.makedirs(self._figures_dir, exist_ok=True)
@@ -93,10 +90,114 @@ class UtilsStats:
93
90
  except Exception as e:
94
91
  print(f"✗ Error guardando figura: {e}")
95
92
 
96
- # ============= MÉTODOS DE ANÁLISIS ESTADÍSTICO =============
93
+ # ============= NUEVO: MÉTODOS DE CARGA DE DATOS =============
94
+
95
+ def load_data(self, path: Union[str, Path], **kwargs) -> pd.DataFrame:
96
+ """
97
+ Carga datos desde archivo en múltiples formatos
98
+
99
+ Parameters:
100
+ -----------
101
+ path : str o Path
102
+ Ruta al archivo de datos
103
+ **kwargs : dict
104
+ Argumentos adicionales para la función de lectura de pandas
105
+
106
+ Returns:
107
+ --------
108
+ pd.DataFrame
109
+ DataFrame con los datos cargados
110
+
111
+ Supported formats:
112
+ ------------------
113
+ - CSV (.csv)
114
+ - Excel (.xlsx, .xls)
115
+ - Text/TSV (.txt, .tsv)
116
+ - JSON (.json)
117
+ - Parquet (.parquet)
118
+ - Feather (.feather)
119
+
120
+ Examples:
121
+ ---------
122
+ >>> utils = UtilsStats()
123
+ >>> df = utils.load_data("datos.csv")
124
+ >>> df = utils.load_data("datos.xlsx", sheet_name="Hoja1")
125
+ >>> df = utils.load_data("datos.json")
126
+ """
127
+ path = Path(path)
128
+
129
+ if not path.exists():
130
+ raise FileNotFoundError(f"El archivo no existe: {path}")
131
+
132
+ ext = path.suffix.lower()
133
+
134
+ try:
135
+ if ext == ".csv":
136
+ df = pd.read_csv(path, **kwargs)
137
+
138
+ elif ext in [".xlsx", ".xls"]:
139
+ df = pd.read_excel(path, **kwargs)
140
+
141
+ elif ext in [".txt", ".tsv"]:
142
+ df = pd.read_table(path, **kwargs)
143
+
144
+ elif ext == ".json":
145
+ df = pd.read_json(path, **kwargs)
146
+
147
+ elif ext == ".parquet":
148
+ df = pd.read_parquet(path, **kwargs)
149
+
150
+ elif ext == ".feather":
151
+ df = pd.read_feather(path, **kwargs)
152
+
153
+ else:
154
+ raise ValueError(f"Formato de archivo no soportado: {ext}")
155
+
156
+ print(f"✓ Datos cargados exitosamente desde: {path}")
157
+ print(f" Shape: {df.shape}")
158
+ print(f" Columnas: {list(df.columns)}")
159
+
160
+ return df
161
+
162
+ except Exception as e:
163
+ raise Exception(f"Error al cargar el archivo {path}: {str(e)}")
97
164
 
98
- def validate_dataframe(self, data: Union[pd.DataFrame, np.ndarray, list]) -> pd.DataFrame:
99
- """Valida y convierte datos a DataFrame"""
165
+ def _resolve_data(self, data: Union[pd.DataFrame, pd.Series, np.ndarray, list, str, Path],
166
+ column: Optional[str] = None) -> Tuple[Union[pd.DataFrame, pd.Series, np.ndarray], str]:
167
+ """
168
+ Resuelve el input de datos: si es una ruta, carga el archivo; si no, usa los datos directamente
169
+
170
+ Returns:
171
+ --------
172
+ Tuple[data, data_source]
173
+ - data: Los datos procesados
174
+ - data_source: String indicando la fuente ('file' o 'memory')
175
+ """
176
+ # Si es string o Path, intentar cargar como archivo
177
+ if isinstance(data, (str, Path)):
178
+ path = Path(data)
179
+ if path.exists():
180
+ df = self.load_data(path)
181
+ if column is not None and column in df.columns:
182
+ return df[column], 'file'
183
+ return df, 'file'
184
+ else:
185
+ raise FileNotFoundError(f"El archivo no existe: {path}")
186
+
187
+ # Si ya son datos en memoria, devolverlos tal cual
188
+ return data, 'memory'
189
+
190
+ # ============= MÉTODOS DE ANÁLISIS ESTADÍSTICO (ACTUALIZADOS) =============
191
+
192
+ def validate_dataframe(self, data: Union[pd.DataFrame, np.ndarray, list, str, Path]) -> pd.DataFrame:
193
+ """
194
+ Valida y convierte datos a DataFrame
195
+
196
+ Ahora acepta también rutas de archivos
197
+ """
198
+ # Intentar resolver si es un archivo
199
+ data, source = self._resolve_data(data)
200
+
100
201
  if isinstance(data, pd.DataFrame):
101
202
  return data
102
203
  elif isinstance(data, np.ndarray):
@@ -117,8 +218,36 @@ class UtilsStats:
117
218
  return f"{num:.{decimals}e}"
118
219
  return f"{num:.{decimals}f}"
119
220
 
120
- def check_normality(self, data: Union[pd.Series, np.ndarray], alpha: float = 0.05) -> dict:
121
- """Verifica si los datos siguen distribución normal usando Shapiro-Wilk"""
221
+ def check_normality(self,
222
+ data: Union[pd.Series, np.ndarray, pd.DataFrame, str, Path],
223
+ column: Optional[str] = None,
224
+ alpha: float = 0.05) -> dict:
225
+ """
226
+ Verifica si los datos siguen distribución normal usando Shapiro-Wilk
227
+
228
+ Parameters:
229
+ -----------
230
+ data : Series, ndarray, DataFrame, str o Path
231
+ Datos a analizar o ruta al archivo
232
+ column : str, optional
233
+ Columna a analizar (si data es DataFrame o archivo)
234
+ alpha : float
235
+ Nivel de significancia
236
+
237
+ Examples:
238
+ ---------
239
+ >>> utils.check_normality("datos.csv", column="edad")
240
+ >>> utils.check_normality(np.random.normal(0, 1, 100))
241
+ """
242
+ # Resolver datos
243
+ data, source = self._resolve_data(data, column)
244
+
245
+ # Extraer array
246
+ if isinstance(data, pd.DataFrame):
247
+ if column is None:
248
+ raise ValueError("Debe especificar 'column' cuando data es DataFrame")
249
+ data = data[column]
250
+
122
251
  if isinstance(data, pd.Series):
123
252
  data = data.dropna().values
124
253
  else:
@@ -135,16 +264,39 @@ class UtilsStats:
135
264
  'interpretation': 'Normal' if shapiro_p > alpha else 'No Normal'
136
265
  }
137
266
 
138
- def calculate_confidence_intervals(self, data: Union[pd.Series, np.ndarray],
267
+ def calculate_confidence_intervals(self,
268
+ data: Union[pd.Series, np.ndarray, pd.DataFrame, str, Path],
269
+ column: Optional[str] = None,
139
270
  confidence_level: float = 0.95,
140
271
  method: str = 'parametric') -> dict:
141
272
  """
142
273
  Calcula intervalos de confianza para la media
274
+
275
+ Parameters:
276
+ -----------
277
+ data : Series, ndarray, DataFrame, str o Path
278
+ Datos a analizar o ruta al archivo
279
+ column : str, optional
280
+ Columna a analizar
281
+ confidence_level : float
282
+ Nivel de confianza (default: 0.95)
283
+ method : str
284
+ 'parametric' o 'bootstrap'
143
285
  """
286
+ # Resolver datos
287
+ data, source = self._resolve_data(data, column)
288
+
289
+ # Extraer array
290
+ if isinstance(data, pd.DataFrame):
291
+ if column is None:
292
+ raise ValueError("Debe especificar 'column' cuando data es DataFrame")
293
+ data = data[column]
294
+
144
295
  if isinstance(data, pd.Series):
145
296
  data_clean = data.dropna().values
146
297
  else:
147
- data_clean = data[~np.isnan(data)]
298
+ data_clean = np.array(data)
299
+ data_clean = data_clean[~np.isnan(data_clean)]
148
300
 
149
301
  n = len(data_clean)
150
302
  mean = np.mean(data_clean)
@@ -185,7 +337,9 @@ class UtilsStats:
185
337
  'method': method
186
338
  }
187
339
 
188
- def detect_outliers(self, data: Union[pd.Series, np.ndarray],
340
+ def detect_outliers(self,
341
+ data: Union[pd.Series, np.ndarray, pd.DataFrame, str, Path],
342
+ column: Optional[str] = None,
189
343
  method: Literal['iqr', 'zscore', 'isolation_forest'] = 'iqr',
190
344
  **kwargs) -> np.ndarray:
191
345
  """
@@ -193,8 +347,10 @@ class UtilsStats:
193
347
 
194
348
  Parameters:
195
349
  -----------
196
- data : array-like
197
- Datos a analizar
350
+ data : Series, ndarray, DataFrame, str o Path
351
+ Datos a analizar o ruta al archivo
352
+ column : str, optional
353
+ Columna a analizar
198
354
  method : str
199
355
  'iqr', 'zscore', o 'isolation_forest'
200
356
 
@@ -203,6 +359,15 @@ class UtilsStats:
203
359
  np.ndarray
204
360
  Array booleano indicando outliers
205
361
  """
362
+ # Resolver datos
363
+ data, source = self._resolve_data(data, column)
364
+
365
+ # Extraer array
366
+ if isinstance(data, pd.DataFrame):
367
+ if column is None:
368
+ raise ValueError("Debe especificar 'column' cuando data es DataFrame")
369
+ data = data[column]
370
+
206
371
  if isinstance(data, pd.Series):
207
372
  data = data.values
208
373
 
@@ -364,7 +529,8 @@ class UtilsStats:
364
529
 
365
530
  return fig
366
531
 
367
- def plot_distribution(self, data: Union[pd.DataFrame, pd.Series, np.ndarray],
532
+ def plot_distribution(self,
533
+ data: Union[pd.DataFrame, pd.Series, np.ndarray, str, Path],
368
534
  column: Optional[str] = None,
369
535
  plot_type: Literal['hist', 'kde', 'box', 'violin', 'all'] = 'hist',
370
536
  backend: Optional[Literal['matplotlib', 'seaborn', 'plotly']] = "seaborn",
@@ -378,10 +544,10 @@ class UtilsStats:
378
544
 
379
545
  Parameters:
380
546
  -----------
381
- data : DataFrame, Series o ndarray
382
- Datos a graficar
547
+ data : DataFrame, Series, ndarray, str o Path
548
+ Datos a graficar o ruta al archivo
383
549
  column : str, optional
384
- Columna a graficar (si data es DataFrame)
550
+ Columna a graficar (si data es DataFrame o archivo)
385
551
  plot_type : str
386
552
  Tipo de gráfico
387
553
  backend : str, optional
@@ -394,11 +560,19 @@ class UtilsStats:
394
560
  Si guardar la figura
395
561
  filename : str, optional
396
562
  Nombre del archivo
563
+
564
+ Examples:
565
+ ---------
566
+ >>> utils.plot_distribution("datos.csv", column="edad")
567
+ >>> utils.plot_distribution(df, column="salario", plot_type="all")
397
568
  """
398
569
  backend = backend or self._plot_backend
399
570
  figsize = figsize or self._default_figsize
400
571
  save_fig = save_fig if save_fig is not None else self._save_fig
401
572
 
573
+ # Resolver datos
574
+ data, source = self._resolve_data(data, column)
575
+
402
576
  # Extraer datos
403
577
  if isinstance(data, pd.DataFrame):
404
578
  if column is None:
@@ -478,7 +652,8 @@ class UtilsStats:
478
652
 
479
653
  return fig
480
654
 
481
- def plot_correlation_matrix(self, data: pd.DataFrame,
655
+ def plot_correlation_matrix(self,
656
+ data: Union[pd.DataFrame, str, Path],
482
657
  method: str = 'pearson',
483
658
  backend: Optional[Literal['seaborn', 'plotly']] = None,
484
659
  figsize: Optional[Tuple[int, int]] = None,
@@ -490,8 +665,8 @@ class UtilsStats:
490
665
 
491
666
  Parameters:
492
667
  -----------
493
- data : DataFrame
494
- Datos para calcular correlación
668
+ data : DataFrame, str o Path
669
+ Datos para calcular correlación o ruta al archivo
495
670
  method : str
496
671
  'pearson', 'spearman' o 'kendall'
497
672
  backend : str, optional
@@ -502,6 +677,12 @@ class UtilsStats:
502
677
  save_fig = save_fig if save_fig is not None else self._save_fig
503
678
  filename = filename or "matriz_correlacion"
504
679
 
680
+ # Resolver datos
681
+ data, source = self._resolve_data(data)
682
+
683
+ if not isinstance(data, pd.DataFrame):
684
+ raise ValueError("Se requiere un DataFrame para calcular matriz de correlación")
685
+
505
686
  # Calcular matriz de correlación
506
687
  corr_matrix = data.corr(method=method)
507
688
 
@@ -553,7 +734,8 @@ class UtilsStats:
553
734
 
554
735
  return fig
555
736
 
556
- def plot_scatter_matrix(self, data: pd.DataFrame,
737
+ def plot_scatter_matrix(self,
738
+ data: Union[pd.DataFrame, str, Path],
557
739
  columns: Optional[List[str]] = None,
558
740
  backend: Optional[Literal['seaborn', 'plotly', 'pandas']] = None,
559
741
  figsize: Optional[Tuple[int, int]] = None,
@@ -562,12 +744,23 @@ class UtilsStats:
562
744
  **kwargs):
563
745
  """
564
746
  Matriz de gráficos de dispersión (pairplot)
747
+
748
+ Parameters:
749
+ -----------
750
+ data : DataFrame, str o Path
751
+ Datos o ruta al archivo
565
752
  """
566
753
  backend = backend or self._plot_backend
567
754
  figsize = figsize or self._default_figsize
568
755
  save_fig = save_fig if save_fig is not None else self._save_fig
569
756
  filename = filename or "scatter_matrix"
570
757
 
758
+ # Resolver datos
759
+ data, source = self._resolve_data(data)
760
+
761
+ if not isinstance(data, pd.DataFrame):
762
+ raise ValueError("Se requiere un DataFrame para matriz de dispersión")
763
+
571
764
  if columns:
572
765
  data = data[columns]
573
766
 
@@ -603,7 +796,7 @@ class UtilsStats:
603
796
  # ============= GRÁFICOS CON INTERVALOS DE CONFIANZA =============
604
797
 
605
798
  def plot_distribution_with_ci(self,
606
- data: Union[pd.DataFrame, pd.Series, np.ndarray],
799
+ data: Union[pd.DataFrame, pd.Series, np.ndarray, str, Path],
607
800
  column: Optional[str] = None,
608
801
  confidence_level: float = 0.95,
609
802
  ci_method: str = 'parametric',
@@ -612,7 +805,14 @@ class UtilsStats:
612
805
  save_fig: Optional[bool] = None,
613
806
  filename: Optional[str] = None,
614
807
  **kwargs) -> plt.Figure:
615
-
808
+ """
809
+ Distribución con intervalos de confianza
810
+
811
+ Ahora acepta rutas de archivos
812
+ """
813
+ # Resolver datos
814
+ data, source = self._resolve_data(data, column)
815
+
616
816
  # ======= PREPARACIÓN =======
617
817
  if isinstance(data, pd.DataFrame):
618
818
  if column is None:
@@ -630,7 +830,7 @@ class UtilsStats:
630
830
  filename = filename or f"distribucion_ci_{data_name.lower().replace(' ', '_')}"
631
831
 
632
832
  # Estadísticas
633
- ci_result = self.calculate_confidence_intervals(data_array, confidence_level, ci_method)
833
+ ci_result = self.calculate_confidence_intervals(data_array, confidence_level=confidence_level, method=ci_method)
634
834
  normality_result = self.check_normality(data_array)
635
835
 
636
836
  # KDE
@@ -739,7 +939,7 @@ class UtilsStats:
739
939
  data_array = data_array[~np.isnan(data_array)]
740
940
 
741
941
  # Calcular estadísticas
742
- ci_result = self.calculate_confidence_intervals(data_array, confidence_level)
942
+ ci_result = self.calculate_confidence_intervals(data_array, confidence_level=confidence_level)
743
943
 
744
944
  # Gráfica izquierda: Distribución básica
745
945
  ax1.hist(data_array, bins=30, alpha=0.7, color=colors[idx],
@@ -779,11 +979,17 @@ class UtilsStats:
779
979
 
780
980
  # ============= MÉTODOS UTILITARIOS ADICIONALES =============
781
981
 
782
- def get_descriptive_stats(self, data: Union[pd.DataFrame, pd.Series, np.ndarray],
982
+ def get_descriptive_stats(self,
983
+ data: Union[pd.DataFrame, pd.Series, np.ndarray, str, Path],
783
984
  column: Optional[str] = None) -> dict:
784
985
  """
785
986
  Obtiene estadísticas descriptivas completas
987
+
988
+ Ahora acepta rutas de archivos
786
989
  """
990
+ # Resolver datos
991
+ data, source = self._resolve_data(data, column)
992
+
787
993
  if isinstance(data, pd.DataFrame):
788
994
  if column is None:
789
995
  raise ValueError("Debe especificar 'column' cuando data es DataFrame")
@@ -810,371 +1016,4 @@ class UtilsStats:
810
1016
  'skewness': stats.skew(data_clean),
811
1017
  'kurtosis': stats.kurtosis(data_clean),
812
1018
  'range': np.max(data_clean) - np.min(data_clean)
813
- }
814
-
815
- def help(self):
816
- """
817
- Muestra ayuda completa de la clase DescriptiveStats
818
- """
819
- help_text = """
820
- ╔════════════════════════════════════════════════════════════════════════════╗
821
- ║ 📊 CLASE UtilsStats - AYUDA COMPLETA ║
822
- ╚════════════════════════════════════════════════════════════════════════════╝
823
-
824
- 📝 DESCRIPCIÓN:
825
- Clase para análisis estadístico descriptivo univariado y multivariado.
826
- Proporciona herramientas para análisis exploratorio de datos, medidas de
827
- tendencia central, dispersión, forma de distribución y regresión lineal.
828
-
829
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
830
-
831
- 📋 MÉTODOS PRINCIPALES:
832
-
833
- ┌────────────────────────────────────────────────────────────────────────────┐
834
- │ 1. 📊 ANÁLISIS ESTADÍSTICO │
835
- └────────────────────────────────────────────────────────────────────────────┘
836
-
837
- • .check_normality(data, alpha=0.05)
838
- Verifica normalidad usando test Shapiro-Wilk
839
- Retorna: dict con estadístico, p-value e interpretación
840
-
841
- • .calculate_confidence_intervals(data, confidence_level=0.95,
842
- method='parametric')
843
- Calcula intervalos de confianza para la media
844
- Métodos: 'parametric' o 'bootstrap'
845
-
846
- • .detect_outliers(data, method='iqr', **kwargs)
847
- Detecta valores atípicos
848
- Métodos: 'iqr', 'zscore', 'isolation_forest'
849
-
850
- • .calculate_effect_size(group1, group2, method='cohen')
851
- Calcula tamaño del efecto entre grupos
852
- Métodos: 'cohen' (Cohen's d) o 'hedges' (Hedges' g)
853
-
854
- • .get_descriptive_stats(data, column=None)
855
- Estadísticas descriptivas completas en un dict
856
-
857
- ┌────────────────────────────────────────────────────────────────────────────┐
858
- │ 2. 🎨 VISUALIZACIÓN DE DISTRIBUCIONES │
859
- └────────────────────────────────────────────────────────────────────────────┘
860
-
861
- • .plot_distribution(data, column=None, plot_type='hist',
862
- backend='seaborn', bins=30, figsize=None,
863
- save_fig=None, filename=None)
864
-
865
- Grafica distribución de una variable
866
-
867
- plot_type: 'hist', 'kde', 'box', 'violin', 'all'
868
- backend: 'matplotlib', 'seaborn', 'plotly'
869
-
870
- • .plot_distribution_with_ci(data, column=None, confidence_level=0.95,
871
- ci_method='parametric', bins=30, figsize=None,
872
- save_fig=None, filename=None)
873
-
874
- Distribución con intervalos de confianza visualizados
875
-
876
- • .plot_multiple_distributions_with_ci(data_dict, confidence_level=0.95)
877
-
878
- Compara múltiples distribuciones con sus IC
879
-
880
- ┌────────────────────────────────────────────────────────────────────────────┐
881
- │ 3. 🎨 VISUALIZACIÓN MULTIVARIADA │
882
- └────────────────────────────────────────────────────────────────────────────┘
883
-
884
- • .plot_correlation_matrix(data, method='pearson', backend='seaborn',
885
- figsize=None, save_fig=None)
886
-
887
- Matriz de correlación con heatmap
888
- Métodos: 'pearson', 'spearman', 'kendall'
889
-
890
- • .plot_scatter_matrix(data, columns=None, backend='seaborn',
891
- figsize=None, save_fig=None)
892
-
893
- Matriz de gráficos de dispersión (pairplot)
894
- Backends: 'seaborn', 'plotly', 'pandas'
895
-
896
- ┌────────────────────────────────────────────────────────────────────────────┐
897
- │ 4. ⚙️ CONFIGURACIÓN │
898
- └────────────────────────────────────────────────────────────────────────────┘
899
-
900
- • .set_plot_backend(backend)
901
- Establece backend por defecto: 'matplotlib', 'seaborn', 'plotly'
902
-
903
- • .set_default_figsize(figsize)
904
- Establece tamaño de figura por defecto: (ancho, alto)
905
-
906
- • .set_save_fig_options(save_fig=False, fig_format='png',
907
- fig_dpi=300, figures_dir='figures')
908
-
909
- Configura guardado automático de figuras
910
-
911
- ┌────────────────────────────────────────────────────────────────────────────┐
912
- │ 5. 🛠️ UTILIDADES │
913
- └────────────────────────────────────────────────────────────────────────────┘
914
-
915
- • .validate_dataframe(data)
916
- Valida y convierte datos a DataFrame
917
-
918
- • .format_number(num, decimals=6, scientific=False)
919
- Formatea números con precisión específica
920
-
921
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
922
-
923
- 💡 EJEMPLOS DE USO:
924
-
925
- ┌─ Ejemplo 1: Configuración Inicial ──────────────────────────────────────┐
926
- │ from utils import UtilsStats │
927
- │ import pandas as pd │
928
- │ import numpy as np │
929
- │ │
930
- │ # Inicializar │
931
- │ utils = UtilsStats() │
932
- │ │
933
- │ # Configurar visualización │
934
- │ utils.set_plot_backend('seaborn') │
935
- │ utils.set_default_figsize((12, 6)) │
936
- │ │
937
- │ # Configurar guardado automático │
938
- │ utils.set_save_fig_options( │
939
- │ save_fig=True, │
940
- │ fig_format='png', │
941
- │ fig_dpi=300, │
942
- │ figures_dir='mis_graficos' │
943
- │ ) │
944
- └──────────────────────────────────────────────────────────────────────────┘
945
-
946
- ┌─ Ejemplo 2: Análisis de Normalidad ─────────────────────────────────────┐
947
- │ # Generar datos │
948
- │ datos_normales = np.random.normal(0, 1, 1000) │
949
- │ datos_no_normales = np.random.exponential(2, 1000) │
950
- │ │
951
- │ # Test de normalidad │
952
- │ resultado1 = utils.check_normality(datos_normales) │
953
- │ print(f"Normales: {resultado1['interpretation']}") │
954
- │ print(f"p-value: {resultado1['shapiro_pvalue']:.4f}") │
955
- │ │
956
- │ resultado2 = utils.check_normality(datos_no_normales) │
957
- │ print(f"No normales: {resultado2['interpretation']}") │
958
- └──────────────────────────────────────────────────────────────────────────┘
959
-
960
- ┌─ Ejemplo 3: Intervalos de Confianza ────────────────────────────────────┐
961
- │ # Método paramétrico │
962
- │ ci_param = utils.calculate_confidence_intervals( │
963
- │ datos_normales, │
964
- │ confidence_level=0.95, │
965
- │ method='parametric' │
966
- │ ) │
967
- │ │
968
- │ print(f"Media: {ci_param['mean']:.3f}") │
969
- │ print(f"IC 95%: [{ci_param['ci_lower']:.3f}, " │
970
- │ f"{ci_param['ci_upper']:.3f}]") │
971
- │ │
972
- │ # Método bootstrap (para datos no normales) │
973
- │ ci_boot = utils.calculate_confidence_intervals( │
974
- │ datos_no_normales, │
975
- │ confidence_level=0.95, │
976
- │ method='bootstrap' │
977
- │ ) │
978
- └──────────────────────────────────────────────────────────────────────────┘
979
-
980
- ┌─ Ejemplo 4: Detección de Outliers ──────────────────────────────────────┐
981
- │ # Método IQR (rango intercuartílico) │
982
- │ datos = np.random.normal(100, 15, 1000) │
983
- │ datos = np.append(datos, [200, 210, -50]) # Agregar outliers │
984
- │ │
985
- │ outliers_iqr = utils.detect_outliers(datos, method='iqr') │
986
- │ print(f"Outliers IQR: {outliers_iqr.sum()}") │
987
- │ │
988
- │ # Método Z-score │
989
- │ outliers_z = utils.detect_outliers( │
990
- │ datos, │
991
- │ method='zscore', │
992
- │ threshold=3 │
993
- │ ) │
994
- │ print(f"Outliers Z-score: {outliers_z.sum()}") │
995
- │ │
996
- │ # Isolation Forest (machine learning) │
997
- │ outliers_if = utils.detect_outliers( │
998
- │ datos, │
999
- │ method='isolation_forest', │
1000
- │ contamination=0.05 │
1001
- │ ) │
1002
- └──────────────────────────────────────────────────────────────────────────┘
1003
-
1004
- ┌─ Ejemplo 5: Tamaño del Efecto ──────────────────────────────────────────┐
1005
- │ # Comparar dos grupos │
1006
- │ grupo_control = np.random.normal(100, 15, 100) │
1007
- │ grupo_tratamiento = np.random.normal(110, 15, 100) │
1008
- │ │
1009
- │ efecto = utils.calculate_effect_size( │
1010
- │ grupo_control, │
1011
- │ grupo_tratamiento, │
1012
- │ method='cohen' │
1013
- │ ) │
1014
- │ │
1015
- │ print(f"Cohen's d: {efecto['effect_size']:.3f}") │
1016
- │ print(f"Interpretación: {efecto['interpretation']}") │
1017
- │ print(f"Diferencia de medias: {efecto['mean_diff']:.2f}") │
1018
- └──────────────────────────────────────────────────────────────────────────┘
1019
-
1020
- ┌─ Ejemplo 6: Gráficos de Distribución ───────────────────────────────────┐
1021
- │ df = pd.DataFrame({ │
1022
- │ 'edad': np.random.normal(35, 10, 500), │
1023
- │ 'salario': np.random.lognormal(10.5, 0.5, 500) │
1024
- │ }) │
1025
- │ │
1026
- │ # Histograma simple │
1027
- │ fig1 = utils.plot_distribution( │
1028
- │ df, │
1029
- │ column='edad', │
1030
- │ plot_type='hist', │
1031
- │ bins=30 │
1032
- │ ) │
1033
- │ │
1034
- │ # Panel completo (histograma, box, violin, Q-Q) │
1035
- │ fig2 = utils.plot_distribution( │
1036
- │ df, │
1037
- │ column='salario', │
1038
- │ plot_type='all', │
1039
- │ backend='seaborn' │
1040
- │ ) │
1041
- │ │
1042
- │ # Con Plotly (interactivo) │
1043
- │ fig3 = utils.plot_distribution( │
1044
- │ df, │
1045
- │ column='edad', │
1046
- │ plot_type='violin', │
1047
- │ backend='plotly' │
1048
- │ ) │
1049
- └──────────────────────────────────────────────────────────────────────────┘
1050
-
1051
- ┌─ Ejemplo 7: Distribución con Intervalos de Confianza ───────────────────┐
1052
- │ # Visualizar distribución con IC │
1053
- │ fig = utils.plot_distribution_with_ci( │
1054
- │ df, │
1055
- │ column='edad', │
1056
- │ confidence_level=0.95, │
1057
- │ ci_method='parametric', │
1058
- │ bins=30, │
1059
- │ save_fig=True, │
1060
- │ filename='edad_con_ic' │
1061
- │ ) │
1062
- │ │
1063
- │ # Comparar múltiples distribuciones │
1064
- │ data_dict = { │
1065
- │ 'Grupo A': df['edad'][:200], │
1066
- │ 'Grupo B': df['edad'][200:400], │
1067
- │ 'Grupo C': df['edad'][400:] │
1068
- │ } │
1069
- │ │
1070
- │ fig = utils.plot_multiple_distributions_with_ci( │
1071
- │ data_dict, │
1072
- │ confidence_level=0.95 │
1073
- │ ) │
1074
- └──────────────────────────────────────────────────────────────────────────┘
1075
-
1076
- ┌─ Ejemplo 8: Matriz de Correlación ──────────────────────────────────────┐
1077
- │ # Crear datos correlacionados │
1078
- │ df = pd.DataFrame({ │
1079
- │ 'A': np.random.normal(0, 1, 100), │
1080
- │ 'B': np.random.normal(0, 1, 100), │
1081
- │ 'C': np.random.normal(0, 1, 100) │
1082
- │ }) │
1083
- │ df['D'] = df['A'] * 0.8 + np.random.normal(0, 0.2, 100) │
1084
- │ │
1085
- │ # Matriz de correlación con seaborn │
1086
- │ fig = utils.plot_correlation_matrix( │
1087
- │ df, │
1088
- │ method='pearson', │
1089
- │ backend='seaborn', │
1090
- │ figsize=(10, 8) │
1091
- │ ) │
1092
- │ │
1093
- │ # Con Plotly (interactiva) │
1094
- │ fig = utils.plot_correlation_matrix( │
1095
- │ df, │
1096
- │ method='spearman', │
1097
- │ backend='plotly' │
1098
- │ ) │
1099
- └──────────────────────────────────────────────────────────────────────────┘
1100
-
1101
- ┌─ Ejemplo 9: Matriz de Dispersión ───────────────────────────────────────┐
1102
- │ # Pairplot completo │
1103
- │ fig = utils.plot_scatter_matrix( │
1104
- │ df, │
1105
- │ columns=['A', 'B', 'C', 'D'], │
1106
- │ backend='seaborn' │
1107
- │ ) │
1108
- │ │
1109
- │ # Con Plotly │
1110
- │ fig = utils.plot_scatter_matrix( │
1111
- │ df, │
1112
- │ backend='plotly' │
1113
- │ ) │
1114
- └──────────────────────────────────────────────────────────────────────────┘
1115
-
1116
- ┌─ Ejemplo 10: Estadísticas Descriptivas Completas ───────────────────────┐
1117
- │ # Obtener todas las estadísticas │
1118
- │ stats = utils.get_descriptive_stats(df, column='edad') │
1119
- │ │
1120
- │ print(f"Media: {stats['mean']:.2f}") │
1121
- │ print(f"Mediana: {stats['median']:.2f}") │
1122
- │ print(f"Desv. Est.: {stats['std']:.2f}") │
1123
- │ print(f"IQR: {stats['iqr']:.2f}") │
1124
- │ print(f"Asimetría: {stats['skewness']:.3f}") │
1125
- │ print(f"Curtosis: {stats['kurtosis']:.3f}") │
1126
- └──────────────────────────────────────────────────────────────────────────┘
1127
-
1128
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1129
-
1130
- 🎯 CARACTERÍSTICAS CLAVE:
1131
-
1132
- ✓ Múltiples backends de visualización (matplotlib, seaborn, plotly)
1133
- ✓ Guardado automático de figuras en alta resolución
1134
- ✓ Análisis estadísticos robustos
1135
- ✓ Detección de outliers con 3 métodos
1136
- ✓ Intervalos de confianza paramétricos y bootstrap
1137
- ✓ Visualizaciones profesionales listas para publicación
1138
- ✓ Manejo automático de valores faltantes
1139
- ✓ Integración perfecta con pandas y numpy
1140
- ✓ Gráficos interactivos con Plotly
1141
-
1142
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1143
-
1144
- 📊 BACKENDS DE VISUALIZACIÓN:
1145
-
1146
- 🔹 Matplotlib:
1147
- • Rápido y ligero
1148
- • Ideal para gráficos simples
1149
- • Mejor para exportar a archivos
1150
-
1151
- 🔹 Seaborn:
1152
- • Gráficos estadísticos elegantes
1153
- • Temas predefinidos atractivos
1154
- • Mejor para análisis exploratorio
1155
-
1156
- 🔹 Plotly:
1157
- • Gráficos interactivos
1158
- • Zoom, pan, hover tooltips
1159
- • Ideal para presentaciones y dashboards
1160
-
1161
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1162
-
1163
- 💡 CONSEJOS Y MEJORES PRÁCTICAS:
1164
-
1165
- 1. Siempre verificar normalidad antes de usar métodos paramétricos
1166
- 2. Usar bootstrap para IC cuando los datos no son normales
1167
- 3. Detectar outliers antes de calcular estadísticas
1168
- 4. Guardar figuras en alta resolución (300 DPI) para publicaciones
1169
- 5. Usar Plotly para presentaciones interactivas
1170
- 6. Usar seaborn para análisis exploratorio rápido
1171
-
1172
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1173
-
1174
- 📚 DOCUMENTACIÓN ADICIONAL:
1175
- Para más información sobre métodos específicos, use:
1176
- help(UtilsStats.nombre_metodo)
1177
-
1178
- ╚════════════════════════════════════════════════════════════════════════════╝
1179
- """
1180
- print(help_text)
1019
+ }