2.- Analisis de datos

2.1.- Entender los datos que disponemos

Entender la estructura de los datos

Fichero dr_EES_2022.xlsx

Este fichero contiene la información sobre qué datos y cómo están codificados.

2.2.- Leer y extraer los datos que nos interesan

import pandas as pd
# Leo los datos
# Cargar el archivo pickle que contiene los datos de salarios
ruta_pickle = r"F:\clase\clase24_25\laboratorio\lab3\datos_2022.pkl"

# Leer el archivo pickle
df_salarios = pd.read_pickle(ruta_pickle)

# Mostrar las primeras filas del DataFrame para inspeccionar los datos
df_salarios.head()

2.3.- Seleccionar las variables que nos interesa

# Definir las listas de variables específicas

variables_salario = ["salbase", "comsal", "extraorm", "phextra"]

variables_horas = ["jsp1", "jsp2", "hextra"]

variables_demograficas = ["sexo", "estu", "cno1", "cnace", "estrato2", "anoanti", "cno1"]

# Crear la lista combinada para la brecha salarial

variables_brecha = variables_salario + variables_horas + variables_demograficas

df_salarios.columns = df_salarios.columns.str.lower()

brecha_df = df_salarios.loc[:,variables_brecha]

brecha_df.head()

2.4.- Construyo las variables que me interesan

brecha_df["salmes"] = brecha_df["salbase"] + brecha_df["comsal"] + brecha_df["extraorm"] + brecha_df["phextra"]
# JMP1=(JSP1+JSP2/60)*4.35 + HEXTRA
brecha_df["horas"] = (brecha_df["jsp1"] + brecha_df["jsp2"]/60)*4.35 + brecha_df["hextra"] 
brecha_df["salario_hora"] = brecha_df["salmes"] / brecha_df["horas"]

2.5.- Primer análisis de la brecha salarial

brecha_df.groupby(["sexo"])["salario_hora"].describe()

2.6.- Densidad por sexo

import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import kde
import seaborn as sns

# Graficamos la densidad del salario por hora ajustada no parametricamente.

# Configurar el tema de seaborn
sns.set_theme(style="whitegrid")

# Diccionario para mapear los valores de 's'
sexo_labels = {1: "Hombre", 6: "Mujer"}


sexo_df = brecha_df.groupby("sexo")["salario_hora"]

for s in sexo_df.groups.keys():
    data = brecha_df.loc[sexo_df.groups[s], "salario_hora"]
    density = kde.gaussian_kde(data)
    x = np.linspace(1,50,100)
    y = density(x)
    plt.plot(x, y, label = sexo_labels[s])
    plt.title("Densidad del salario por hora")
    plt.xlabel("Euros por hora")
    
plt.legend()
plt.show()

2.6.1- Densidad por sexo: inserta la mediana en el gráfico

import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import kde

# Verificar que 'brecha_df' esté definido con las columnas necesarias
try:
    # Diccionario para mapear valores de 's' a etiquetas y colores
    sexo_labels = {1: "Hombre", 6: "Mujer"}
    sexo_colors = {1: "blue", 6: "red"}  # Azul para hombres, rojo para mujeres

    # Agrupar por sexo
    sexo_df = brecha_df.groupby("sexo")["salario_hora"]

    plt.figure(figsize=(10, 6))  # Ajustar el tamaño del gráfico

    # Iterar sobre los grupos (Hombre y Mujer)
    for s in sexo_df.groups.keys():
        data = brecha_df.loc[sexo_df.groups[s], "salario_hora"]
        density = kde.gaussian_kde(data)
        x = np.linspace(1, 50, 100)
        y = density(x)
        color = sexo_colors.get(s, "gray")  # Color para la densidad y la línea
        plt.plot(x, y, color=color, label=sexo_labels.get(s, f"Otro ({s})"))

        # Agregar línea vertical para la mediana con el mismo color
        median = np.median(data)
        plt.axvline(median, color=color, linestyle='--', 
                    label=f"Mediana {sexo_labels.get(s, f'Otro ({s})')}: {median:.2f}")

    # Título y etiquetas
    plt.title("Densidad del salario por hora")
    plt.xlabel("Euros por hora")
    plt.ylabel("Densidad")

    # Mostrar leyenda
    plt.legend(title="Sexo")
    plt.show()

except NameError:
    print("El DataFrame 'brecha_df' no está definido en el entorno actual.")
except KeyError as e:
    print(f"El DataFrame 'brecha_df' no tiene la columna esperada: {e}.")

2.6.1: Densidad: insertá también la media

# Verificar que 'brecha_df' esté definido con las columnas necesarias
try:
    # Diccionario para mapear valores de 's' a etiquetas y colores
    sexo_labels = {1: "Hombre", 6: "Mujer"}
    sexo_colors = {1: "blue", 6: "red"}  # Azul para hombres, rojo para mujeres

    # Agrupar por sexo
    sexo_df = brecha_df.groupby("sexo")["salario_hora"]

    plt.figure(figsize=(10, 6))  # Ajustar el tamaño del gráfico

    # Iterar sobre los grupos (Hombre y Mujer)
    for s in sexo_df.groups.keys():
        data = brecha_df.loc[sexo_df.groups[s], "salario_hora"]
        density = kde.gaussian_kde(data)
        x = np.linspace(1, 50, 100)
        y = density(x)
        color = sexo_colors.get(s, "gray")  # Color para la densidad y las líneas
        plt.plot(x, y, color=color, label=sexo_labels.get(s, f"Otro ({s})"))

        # Agregar línea vertical para la mediana con el mismo color
        median = np.median(data)
        plt.axvline(median, color=color, linestyle='--', 
                    label=f"Mediana {sexo_labels.get(s, f'Otro ({s})')}: {median:.2f}")

        # Agregar línea vertical para la media con el mismo color
        mean = np.mean(data)
        plt.axvline(mean, color=color, linestyle=':', 
                    label=f"Media {sexo_labels.get(s, f'Otro ({s})')}: {mean:.2f}")

    # Título y etiquetas
    plt.title("Densidad del salario por hora")
    plt.xlabel("Euros por hora")
    plt.ylabel("Densidad")

    # Quitar grids

    plt.grid(False)

    # Mostrar leyenda
    plt.legend(title="Sexo")
    plt.show()

except NameError:
    print("El DataFrame 'brecha_df' no está definido en el entorno actual.")
except KeyError as e:
    print(f"El DataFrame 'brecha_df' no tiene la columna esperada: {e}.")
## El DataFrame 'brecha_df' no está definido en el entorno actual.

Función de Distribución con mediana

import numpy as np
import matplotlib.pyplot as plt

# Diccionario para mapear valores de 's' a etiquetas y colores
sexo_labels = {1: "Hombre", 6: "Mujer"}
sexo_colors = {1: "blue", 6: "red"}  # Azul para hombres, rojo para mujeres

# Crear la figura
plt.figure(figsize=(10, 6))

# Iterar sobre los grupos (Hombre y Mujer)
for s, group_data in brecha_df.groupby("sexo"):
    data = group_data["salario_hora"].dropna()  # Asegurarse de no incluir valores nulos

    # Cortar los salarios en el percentil 90
    p90 = np.percentile(data, 90)
    data = data[data <= p90]

    # Calcular la ECDF
    sorted_data = np.sort(data)  # Ordenar los datos
    ecdf = np.arange(1, len(sorted_data) + 1) / len(sorted_data)  # Calcular la ECDF
    color = sexo_colors.get(s, "gray")  # Asignar color

    # Graficar la ECDF
    plt.step(sorted_data, ecdf, color=color, label=sexo_labels.get(s, f"Otro ({s})"))

    # Calcular y agregar línea vertical y horizontal para la mediana
    median = np.median(data)
    cdf_median = np.searchsorted(sorted_data, median) / len(sorted_data)  # Obtener el valor acumulado en la mediana
    plt.axvline(median, color=color, linestyle='--', ymax=cdf_median, label=f"Mediana {sexo_labels[s]}: {median:.2f}")
    plt.axhline(cdf_median, color=color, linestyle='--', xmax=median / sorted_data.max(), alpha=0.5)

# Título y etiquetas
plt.title("Distribución acumulada del salario por hora (cortado en percentil 90)")
plt.xlabel("Euros por hora")
plt.ylabel("Probabilidad acumulada")

# Quitar grids
plt.grid(False)

# Quitar los ejes superior y derecho
plt.gca().spines['top'].set_visible(False)
plt.gca().spines['right'].set_visible(False)

# Mostrar leyenda
plt.legend(title="Sexo")
plt.show()