0% encontró este documento útil (0 votos)
7 vistas16 páginas

Guía Completa de Análisis de Datos Con Python

El documento detalla un análisis exploratorio de datos utilizando Python y la librería pandas, comenzando con la documentación y descripción de los datos. Se abordan técnicas para filtrar columnas por tipo, realizar análisis descriptivos, detectar y tratar valores nulos y duplicados, así como identificar y manejar outliers. Además, se incluyen métodos para visualizar distribuciones y comparar datos antes y después del tratamiento de outliers.
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
7 vistas16 páginas

Guía Completa de Análisis de Datos Con Python

El documento detalla un análisis exploratorio de datos utilizando Python y la librería pandas, comenzando con la documentación y descripción de los datos. Se abordan técnicas para filtrar columnas por tipo, realizar análisis descriptivos, detectar y tratar valores nulos y duplicados, así como identificar y manejar outliers. Además, se incluyen métodos para visualizar distribuciones y comparar datos antes y después del tratamiento de outliers.
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 16

INICIO DE ANALISIS EXPLORAATORIO

1. ANALISIS Y DESCRIPCION GENERAL ANTES DE TRATARLOS

1. Documentar los datos antes de tratarlos

import pandas as pd

# 1. Mostrar información general del DataFrame


df.info()

# 2. Ver las primeras filas para entender la estructura


print(df.head())

# 3. Resumen estadístico y de tipos para todas las columnas


print(df.describe(include='all').T)

Explicación:

1.

import pandas as pd
Importa pandas, la librería estándar para manipulación de datos tabulares.
2. df.info()
Muestra el número de filas, columnas, tipo de dato de cada columna y cuántos valores no nulos
hay.
3. print(df.head())
Enseña las primeras 5 filas; útil para ver ejemplos concretos de los valores.
df.describe(include='all').T
include='all': incluye numéricas y categóricas.
.T: transpone la tabla para que cada fila sea una variable, y las columnas estadísticas (count,
unique, top, mean, etc.).

2. Filtrar columnas por tipo (numéricas, categóricas, fechas…)

# 1. Columnas numéricas
numeric_cols = df.select_dtypes(include=['number']).columns.tolist()

# 2. Columnas categóricas (texto o category)


categorical_cols = df.select_dtypes(include=['object', 'category']).columns.tolist()

# 3. Columnas datetime
datetime_cols = df.select_dtypes(include=['datetime64[ns]']).columns.tolist()

# 4. Mostrar resultados
print("Columnas numéricas: ", numeric_cols)
print("Columnas categóricas: ", categorical_cols)
print("Columnas de fecha: ", datetime_cols)
Explicación:

1.

df.select_dtypes(include=['number'])
Selecciona todas las columnas cuyo dtype sea un subtipo numérico (int, float).
2. df.select_dtypes(include=['object', 'category'])
Coge las columnas de tipo texto (object) o category.
3. df.select_dtypes(include=['datetime64[ns]'])
Detecta columnas ya parseadas como fechas.
4. .columns.tolist()
Extrae la lista de nombres de columna para usar después.
5. print(...)
Muestra por consola en tres listados separados.

3. Análisis descriptivo por tipo de variable


# 1. Estadísticos de las variables numéricas
desc_num = df[numeric_cols].describe().T
print(desc_num)

# 2. Resumen de las variables categóricas


desc_cat = df[categorical_cols].describe().T
print(desc_cat)

Explicación:

1.

df[numeric_cols].describe()
Aplica describe sólo a las numéricas (count, mean, std, min, 25%, 50%, 75%, max).
2. df[categorical_cols].describe()
Para categóricas muestra (count, unique, top, freq).
3. .T
Transpone para que cada variable sea una fila y las estadísticas, columnas.
4. print(...)
Permite inspeccionar fácilmente ambos resúmenes.

4. Resumen de dtypes, valores únicos y nulos

# 1. Crear un DataFrame resumen

dtype_summary = pd.DataFrame({

'columna': df.columns,

'dtype': df.dtypes.astype(str),

'n_unique': df.nunique(),

'n_null': df.isnull().sum()
})

# 2. Mostrar el resumen

print(dtype_summary)

Explicación:

1.

df.columns
Lista de nombres de todas las columnas.
2. df.dtypes.astype(str)
Convierte el tipo de dato de cada columna a string para legibilidad.
3. df.nunique()
Cuenta los valores distintos por columna.
4. df.isnull().sum()
Cuenta cuántos valores faltantes hay en cada columna.
5. Armamos un nuevo DataFrame con esa info para tener todo en una sola tabla.

5. Cambiar el formato de columnas a su tipo correcto

Nota: ajusta las listas to_datetime_cols, to_category_cols, etc., con los


nombres de tus columnas reales.

# 1. Convertir columnas a datetime

to_datetime_cols = ['fecha_registro', 'fecha_ultima_compra']

for col in to_datetime_cols:

df[col] = pd.to_datetime(df[col], errors='coerce', dayfirst=True)

# 2. Convertir columnas a categórico

to_category_cols = ['pais', 'categoria_cliente']

for col in to_category_cols:

df[col] = df[col].astype('category')

# 3. Convertir columnas a numérico

to_numeric_cols = ['total_compras', 'cantidad_pedidos']

for col in to_numeric_cols:

df[col] = pd.to_numeric(df[col], errors='coerce')

# 4. Asegurar columnas de texto como string

to_string_cols = ['nombre', 'email']

for col in to_string_cols:

df[col] = df[col].astype(str)
Explicación:

Fechas:
pd.to_datetime(...) convierte cadenas a datetime64.
errors='coerce' convierte formatos inválidos en NaT.
dayfirst=True asume formato día/mes/año (ajusta según tu origen).

Categórico:
astype('category') ahorra memoria y es útil para análisis de categorías.

Numérico:
pd.to_numeric(..., errors='coerce') convierte strings con números a float o int, y deja NaN si hay
errores.

Texto:
astype(str) garantiza dtype object con strings (ideal después de operaciones que mezclan
tipos).

detectar , rellenar y documentas datos ausentes y nulos


DETECTAR Y DOCUMENTAR VALORES
# 1. Detectar y documentar valores ausentes

# Mostrar número de valores nulos por columna


null_counts = df.isnull().sum()

# Mostrar porcentaje de valores nulos por columna


null_percents = df.isnull().mean() * 100

# Combinar en un solo DataFrame de resumen


missing_summary = pd.DataFrame({
'n_nulos': null_counts,
'pct_nulos': null_percents
}).sort_values(by='pct_nulos', ascending=False)

print(missing_summary)

Explicación:
1.

df.isnull()
Genera un DataFrame booleano (True = valor nulo, False = no nulo).
2. .sum()
Al sumar en el eje de filas, cuenta cuántos True (nulos) hay en cada columna.
3. .mean()
Promedia los valores booleanos (True=1, False=0), dando el proporción de nulos.
4. * 100
Pasa esa proporción a porcentaje.
5. pd.DataFrame({...})
Construye un DataFrame con ambas métricas (n_nulos y pct_nulos).
6. .sort_values(...)
Ordena las columnas de mayor a menor % de nulos para priorizar limpieza.
7. print(...)
Muestra el resumen en consola.

Calcular valores de relleno por columna

# 2. Calcular valores de relleno por columna

# a) Para numéricas: media

fill_mean = df[numeric_cols].mean()

# b) Para categóricas: moda (valor más frecuente)

fill_mode = df[categorical_cols].mode().iloc[0]

# Mostrar ambos

print("Valores medios (numéricas):\n", fill_mean)

print("\nValores más frecuentes (categóricas):\n", fill_mode)

Explicación:

1.

df[numeric_cols].mean()
Calcula la media de cada columna numérica automáticamente (ignora nulos).
2. df[categorical_cols].mode()
Devuelve un DataFrame con las modas de cada columna categórica.
3. .iloc[0]
Selecciona la primera fila de modas (en caso de empates, cualquiera).
4. print(...)
Permite ver qué valor usarás para rellenar.

Rellenar valores ausentes colum a colum

# 3. Rellenar valores ausentes columna a columna

# Ejemplo de esquema: dict que asocia cada columna con su valor de relleno

custom_fill = {

'total_compras': fill_mean['total_compras'], # media

'categoria_cliente': fill_mode['categoria_cliente'], # moda


'pais': 'Desconocido', # valor fijo
# agrega más según necesites...

# Aplicar el relleno
f l li fill i
for col, val in custom_fill.items():

df[col].fillna(val, inplace=True)

# 4. Verificar que no queden valores faltantes

print(df.isnull().sum())

Explicación:

1.

custom_fill = { ... }
Diccionario donde clave=nombre de columna, valor=qué rellenar.
2. for col, val in custom_fill.items():
Itera sobre cada par (columna, valor).
df[col].fillna(val, inplace=True)
fillna(val): rellena todos los NaN de esa columna con val.
inplace=True: modifica el DataFrame original sin crear copia.
3. Explicación:
4.

df.isnull().sum()
Repite el conteo de nulos por columna para confirmar que todos sean cero.
5. print(...)
Muestra la verificación final.

Detectar y tratar duplicados

# 5. Detectar y tratar duplicados

# a) Contar cuántas filas están duplicadas (todas las columnas igual)

n_duplicados = df.duplicated().sum()

print(f"Filas duplicadas: {n_duplicados}")

# b) Mostrar ejemplos de duplicados (opcional)

duplicados = df[df.duplicated(keep=False)]

print(duplicados.head())

# c) Eliminar duplicados

df.drop_duplicates(inplace=True)

# d) Confirmar que ya no hay duplicados

print("Duplicados después de drop:", df.duplicated().sum())

Explicación:

1.

df.duplicated()
Devuelve una Serie booleana señalando las filas que repiten valores con una anterior.
2. .sum()
Cuenta cuántas son True (duplicados).
3. df[df.duplicated(keep=False)]
Filtra todas las filas que aparecen más de una vez (keep=False marca todas las copias).
4. df.drop_duplicates(inplace=True)
Elimina las filas duplicadas dejando solo la primera aparición.
5. df.duplicated().sum()
Comprueba que ya no hay duplicados (debería ser 0).

DETECTAR VALORES ATIPICOS O OUTLIERS


1. Detectar outliers numéricos con el método IQR

import pandas as pd
import numpy as np

# 1. Identificar columnas numéricas


numeric_cols = df.select_dtypes(include=['number']).columns.tolist()

# 2. Calcular los límites IQR para cada columna


outlier_bounds = {}
for col in numeric_cols:
Q1 = df[col].quantile(0.25)
Q3 = df[col].quantile(0.75)
IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
outlier_bounds[col] = (lower_bound, upper_bound)

# 3. Mostrar límites para inspección


print("Límites IQR por columna:")
for col, (low, high) in outlier_bounds.items():
print(f" - {col}: [{low:.2f}, {high:.2f}]")

Explicación detallada

1.
import pandas as pd, import numpy as np
Cargamos pandas y numpy para manipulación de datos y cálculos numéricos.
2. df.select_dtypes(include=['number'])
Selecciona únicamente las columnas numéricas (int, float).
3. .columns.tolist()
Extrae la lista de nombres de esas columnas.
4. Bucle for col in numeric_cols:
Itera sobre cada variable numérica.
5. df[col].quantile(0.25) / .quantile(0.75)
Calcula el primer (Q1) y tercer cuartil (Q3).
6. IQR = Q3 - Q1
Rango intercuartílico.
7. lower_bound = Q1 - 1.5 * IQR
Límite inferior para atípicos.
8. upper_bound = Q3 + 1.5 * IQR
Límite superior.
9. outlier_bounds[col] = (lower_bound, upper_bound)
Guardamos ambos límites en un diccionario.
10. El bucle final imprime cada par de límites para que los revises.

2. Visualizar la distribución con histogramas y boxplots

import matplotlib.pyplot as plt

# 1. Histograma para cada variable numérica


for col in numeric_cols:
plt.figure()
df[col].hist(bins=30)
plt.title(f"Histograma de {col}")
plt.xlabel(col)
plt.ylabel("Frecuencia")
plt.show()

# 2. Boxplot para cada variable numérica


for col in numeric_cols:
plt.figure()
df.boxplot(column=col)
plt.title(f"Boxplot de {col}")
plt.ylabel(col)
plt.show()

Explicación detallada

1.

import matplotlib.pyplot as plt


Carga Matplotlib para generar gráficos.
2. Bucle for col in numeric_cols:
Recorre cada variable numérica.
3. plt.figure()
Crea una nueva figura para cada gráfico.
4. df[col].hist(bins=30)
Dibuja un histograma con 30 barras.
5. plt.title(), plt.xlabel(), plt.ylabel()
Etiquetas y título para entender el gráfico.
6. plt.show()
Muestra el histograma.
7. En el segundo bucle usamos df.boxplot(column=col) para el boxplot, etiquetándolo de forma
similar.

3. Eliminar outliers y crear un DataFrame limpio

# 1. Construir condición compuesta: dentro de los límites para todas las columnas

conds = []

for col, (low, high) in outlier_bounds.items():

conds.append(df[col].between(low, high))

# 2. Combinar todas las condiciones con AND

all_inliers = np.logical_and.reduce(conds)

# 3. DataFrame sin outliers

df_no_outliers = df[all_inliers].copy()

# 4. Verificar número de filas antes y después

print(f"Original: {len(df)} filas")

print(f"Sin outliers: {len(df_no_outliers)} filas")

Explicación detallada

1.

df[col].between(low, high)
Devuelve una Serie booleana: True si el valor está entre los límites, False si es outlier.
2. conds.append(...)
Guardamos esa condición para cada columna.
3. np.logical_and.reduce(conds)
Aplica un “AND” sobre todas las Series booleanas, resultando True solo para filas que son inliers
en todas las variables.
4. df[all_inliers].copy()
Filtra las filas que cumplen la condición y crea una copia en df_no_outliers.
5. Los print finales comparan el tamaño original y el filtrado.

4. Re-generar boxplots para comparar


# Comparar boxplots de una variable antes y después

col = numeric_cols[0] # elige la primera variable para el ejemplo

plt.figure(figsize=(8, 4))
# Antes

plt.subplot(1, 2, 1)

df.boxplot(column=col)

plt.title(f"Con outliers: {col}")

# Después

plt.subplot(1, 2, 2)

df_no_outliers.boxplot(column=col)

plt.title(f"Sin outliers: {col}")

plt.tight_layout()

plt.show()

Explicación detallada

1.

plt.figure(figsize=(8, 4))
Define el tamaño de la figura para dos subgráficos lado a lado.
2. plt.subplot(1, 2, 1) / (1, 2, 2)
Crea dos paneles: el primero para el DataFrame original, el segundo para el limpio.
3. df.boxplot(column=col) / df_no_outliers.boxplot(column=col)
Dibuja los boxplots comparativos.
4. plt.tight_layout()
Ajusta automáticamente los márgenes para que no se sobrepongan.
5. plt.show()
Muestra la comparación.

5. Tratar “outliers” en variables categóricas (categorías muy raras)


# 1. Identificar columnas categóricas
categorical_cols = df.select_dtypes(include=['object', 'category']).columns.tolist()

# 2. Calcular proporción de cada categoría

rare_threshold = 0.05 # por ejemplo, menos del 5%


to_remove = {}

for col in categorical_cols:

freqs = df[col].value_counts(normalize=True)
rare_cats = freqs[freqs < rare_threshold].index.tolist()
to_remove[col] = rare_cats

# 3. Mostrar qué categorías son raras


i í
print("Categorías raras (<5%):")
for col, cats in to_remove.items():

print(f" - {col}: {cats}")

# 4. Eliminar filas con esas categorías raras (opción A)


df_cat_filtered = df.copy()

for col, cats in to_remove.items():


df_cat_filtered = df_cat_filtered[~df_cat_filtered[col].isin(cats)]

# 5. Verificar reducciones
print(f"Antes: {len(df)} filas, Después de eliminar raras: {len(df_cat_filtered)} filas")

Explicación detallada

1. df.select_dtypes(include=['object','category'])
Encuentra las columnas categóricas.
2. df[col].value_counts(normalize=True)
Obtiene la frecuencia relativa (proporción) de cada categoría.
3. freqs[freqs < rare_threshold].index.tolist()
Lista las categorías cuya proporción es menor al umbral (p.ej. 5%).
4. df[col].isin(cats)
Marca las filas que pertenecen a esas categorías raras.
5. df_cat_filtered = df_cat_filtered[~...]
Filtra para quedarnos solo con las filas que no están en esas categorías.
6. El print final compara la cantidad de filas antes y después.

CORRELACION ENTRE VARIABLES

1. Matriz de correlación y heatmap (solo variables numéricas)

import pandas as pd

import numpy as np

import matplotlib.pyplot as plt

# 1. Seleccionar solo columnas numéricas

numeric_cols = df.select_dtypes(include=['number']).columns

# 2. Calcular la matriz de correlación de Pearson

corr_matrix = df[numeric_cols].corr(method='pearson')

# 3. Mostrar la matriz en consola

print(corr_matrix)

# 4. Graficar heatmap con matplotlib

plt.figure(figsize=(8, 6))
im = plt.imshow(corr_matrix, vmin=-1, vmax=1, cmap='coolwarm')

plt.colorbar(im, label='Coeficiente de correlación')

plt.xticks(range(len(numeric_cols)), numeric_cols, rotation=45, ha='right')

plt.yticks(range(len(numeric_cols)), numeric_cols)

plt.title('Heatmap de correlación (Pearson)')

plt.tight_layout()

plt.show()

Explicación:

1.

df.select_dtypes(include=['number'])
→ Filtra únicamente las columnas de tipo numérico (enteros y flotantes).
2. .corr(method='pearson')
→ Calcula la correlación lineal de Pearson para cada par de esas variables.
3. print(corr_matrix)
→ Te permite inspeccionar la tabla de coeficientes en texto.
4. plt.imshow(corr_matrix, vmin=-1, vmax=1, cmap='coolwarm')
→ Dibuja una imagen matricial donde el color indica el valor de correlación (de −1 a +1).
5. plt.colorbar(...)
→ Añade la barra lateral con la escala de colores y su leyenda.
6. plt.xticks(...), plt.yticks(...)
→ Etiquetan los ejes con los nombres de las variables, rotando las etiquetas X para legibilidad.
7. plt.tight_layout()
→ Ajusta márgenes para que no se monten las etiquetas.

Interpretación rápida del heatmap:

Casillas rojas fuertemente positivas (cerca de +1) → variables muy correlacionadas en el mismo sentido.
Azules intensos (cerca de −1) → variables fuertemente inversamente correlacionadas.
Casi blancas (cerca de 0) → poca o ninguna correlación lineal.

2. Scatter plot con coeficiente en el título

from scipy.stats import pearsonr

# Elige dos variables numéricas para el ejemplo

x_col = 'total_compras'

y_col = 'cantidad_pedidos'

# 1. Calcular coeficiente y p-valor

r_value, p_value = pearsonr(df[x_col], df[y_col])

# 2. Graficar dispersión

plt.figure(figsize=(6, 5))

plt.scatter(df[x_col], df[y_col], alpha=0.6)

plt.xlabel(x_col)

plt.ylabel(y_col)
plt.title(f'Dispersión {x_col} vs {y_col}\nPearson r={r_value:.2f}, p={p_value:.3f}')

plt.grid(True)

plt.show()

Explicación:

1.

from scipy.stats import pearsonr


→ Importa la función que calcula Pearson y su significancia (p-valor).
2. pearsonr(df[x_col], df[y_col])
→ Devuelve (r, p) donde r es el coeficiente de correlación y p la probabilidad de obtenerlo por
azar.
3. plt.scatter(...)
→ Dibuja cada punto (x, y); alpha=0.6 añade transparencia para ver la densidad.
4. plt.title(...)
→ Incluye r y p en el título, para documentar directamente la fuerza y fiabilidad.
5. plt.grid(True)
→ Añade rejilla para facilitar lectura de valores.

Interpretación del scatter:

Nube de puntos con pendiente positiva → correlación positiva.


Dispersión descendente → correlación negativa.
Sin patrón claro → muy poca correlación (r cerca de 0).

3. PCA sobre variables numéricas

from sklearn.decomposition import PCA

from sklearn.preprocessing import StandardScaler

# 1. Estandarizar los datos (media 0, varianza 1)

scaler = StandardScaler()

X_scaled = scaler.fit_transform(df[numeric_cols])

# 2. Ajustar PCA

pca = PCA(n_components=min(len(numeric_cols), 5)) # hasta 5 componentes o menos

X_pca = pca.fit_transform(X_scaled)

# 3. Varianza explicada

explained = pca.explained_variance_ratio_

print("Varianza explicada por componente:", explained)

# 4. Cargar matriz de componentes (loadings)

loadings = pd.DataFrame(pca.components_.T,

index=numeric_cols,

l f i f ii l l i d
columns=[f'PC{i+1}' for i in range(len(explained))])

print(loadings)

Explicación:
1.

StandardScaler()
→ Normaliza cada variable para que tengan media 0 y desviación estándar 1, requisito de
PCA.
2. scaler.fit_transform(...)
→ Ajusta el escalador a tus datos y los transforma.
3. PCA(n_components=…)
→ Crea el modelo PCA solicitando hasta 5 componentes o el número de variables si es
menor.
4. pca.fit_transform(X_scaled)
→ Calcula los componentes principales y proyecta tus datos en ellos.
5. explained_variance_ratio_
→ Proporción de la varianza total explicada por cada componente.
6. pca.components_
→ Matriz donde cada fila es un componente y las columnas son los “loadings” para cada
variable.
7. Montamos un DataFrame loadings para ver qué variables aportan más a cada PC.

Interpretación del PCA:

Los primeros PCs son combinaciones lineales que capturan la mayor parte de la varianza.
Si dos variables están muy correlacionadas, aparecerán con loadings de igual signo en el
mismo componente.
Permite reducir dimensionalidad o detectar redundancias.

4. Correlación entre variables categóricas (Cramér’s V)

import pandas as pd

import numpy as np

from scipy.stats import chi2_contingency

def cramers_v(x, y):

contingency = pd.crosstab(x, y)

chi2, _, _, _ = chi2_contingency(contingency)

n = contingency.sum().sum()

phi2 = chi2 / n

r, k = contingency.shape

return np.sqrt(phi2 / (min(r-1, k-1)))

# Ejemplo: matriz de Cramér’s V para todas las categóricas


cat_cols = df.select_dtypes(include=['object', 'category']).columns

cramers = pd.DataFrame(index=cat_cols, columns=cat_cols, dtype=float)

for c1 in cat_cols:

for c2 in cat_cols:

cramers.loc[c1, c2] = cramers_v(df[c1], df[c2])

print(cramers)

Explicación:
1.
pd.crosstab(x, y)
→ Tabla de contingencia entre dos categorías.
2. chi2_contingency(...)
→ Calcula el estadístico χ² de independencia.
3. phi2 = chi2 / n
→ Estadístico φ² normalizado por tamaño muestral n.
4. np.sqrt(phi2 / (min(r-1, k-1)))
→ Formula de Cramér’s V que va de 0 a 1.
5. El doble bucle construye la matriz completa para todas las variables categóricas.

Interpretación de Cramér’s V:

Cercano a 0 → casi independencia entre categorías.


Cercano a 1 → fuerte asociación (cierta combinación de categorías aparece casi siempre
junta).

5. Correlación mixta (numérica vs. binaria: Point-Biserial)

from scipy.stats import pointbiserialr

# Supongamos df['es_premium'] es una variable binaria (0/1)

num_col = 'total_compras'

bin_col = 'es_premium'

r_pb, p_pb = pointbiserialr(df[bin_col], df[num_col])

print(f"Point-Biserial r={r_pb:.2f}, p={p_pb:.3f}")

Explicación:

1.

pointbiserialr(x, y)
→ Calcula la correlación entre variable binaria x y continua y.
2. r_pb
→ Indica si los valores altos de la variable numérica se asocian con la categoría 1 o con la
0.
3. p_pb
→ Significancia estadística de esa asociación.

También podría gustarte