Análisis exploratorio de datos para calificación crediticia con Python

proyecto, a menudo resulta tentador saltar al modelado. Sin embargo, el primer paso y el más importante es comprender los datos.

En nuestra publicación anterior, presentamos cómo se construyen las bases de datos utilizadas para crear modelos de calificación crediticia. También destacamos la importancia de hacer las preguntas correctas:

¿Quiénes son los clientes? ¿Qué tipos de préstamos se conceden? ¿Qué características parecen explicar el riesgo de incumplimiento?

En este artículo, ilustramos este paso fundamental utilizando un conjunto de datos de código abierto disponible en Kaggle: el conjunto de datos de puntuación crediticia. Este conjunto de datos contiene 32.581 observaciones y 12 variables que describen préstamos emitidos por un banco a prestatarios individuales.

Estos préstamos cubren una variedad de necesidades de financiamiento (médicas, personales, educativas y profesionales), así como operaciones de consolidación de deudas. Los montos de los préstamos oscilan entre $500 y $35,000.

Las variables capturan dos dimensiones:

características del contrato (monto del préstamo, tasa de interés, propósito del financiamiento, calificación crediticia y tiempo transcurrido desde la originación del préstamo), características del prestatario (edad, ingresos, años de experiencia profesional y situación de la vivienda).

La variable objetivo del modelo es el incumplimiento, que toma el valor 1 si el cliente está en incumplimiento y 0 en caso contrario.

Hoy en día, muchas herramientas y un número cada vez mayor de agentes de IA son capaces de generar automáticamente descripciones estadísticas de conjuntos de datos. Sin embargo, realizar este análisis manualmente sigue siendo un ejercicio excelente para principiantes. Genera una comprensión más profunda de la estructura de datos, ayuda a resaltar posibles anomalías y respalda la identificación de variables que pueden predecir el riesgo.

En este artículo, adoptamos un enfoque instructivo simple para describir estadísticamente cada variable en el conjunto de datos.

Para las variables categóricas, analizamos el número de observaciones y la tasa de incumplimiento para cada categoría. Para variables continuas, las discretizamos en cuatro intervalos definidos por los cuartiles: ]min; P1], ]P1; P2], ]P2; P3] y ]P3; máximo]

Luego aplicamos el mismo análisis descriptivo a estos intervalos que para las variables categóricas. Esta segmentación es arbitraria y podría ser reemplazada por otros métodos de discretización. El objetivo es simplemente obtener una lectura inicial de cómo se comporta el riesgo en las diferentes características del préstamo y del prestatario.

Estadísticas descriptivas del conjunto de datos de modelado

Distribución de la variable objetivo (loan_status)

Esta variable indica si el préstamo concedido a una contraparte ha dado lugar a un incumplimiento de pago. Toma dos valores: 0 si el cliente no está en mora y 1 si el cliente está en mora.

Más del 78% de los clientes no han incumplido. El conjunto de datos está desequilibrado y es importante tener en cuenta este desequilibrio durante el modelado.

La siguiente variable relevante a analizar sería la temporal. Nos permitiría estudiar cómo evoluciona la tasa de impago a lo largo del tiempo, verificar su estacionariedad y evaluar su estabilidad y previsibilidad.

Lamentablemente, el conjunto de datos no contiene información temporal. No sabemos cuándo se registró cada observación, lo que hace imposible determinar si los préstamos se otorgaron durante un período de estabilidad económica o durante una recesión.

No obstante, esta información es esencial en la modelización del riesgo crediticio. El comportamiento de los prestatarios puede variar significativamente según el entorno macroeconómico. Por ejemplo, durante las crisis financieras (como la crisis de las hipotecas de alto riesgo de 2008 o la pandemia de COVID-19) las tasas de impago suelen aumentar considerablemente en comparación con períodos económicos más favorables.

Por lo tanto, la ausencia de una dimensión temporal en este conjunto de datos limita el alcance de nuestro análisis. En particular, nos impide estudiar cómo evoluciona la dinámica del riesgo a lo largo del tiempo y evaluar la posible solidez de un modelo frente a los ciclos económicos.

Sin embargo, tenemos acceso a la variable cb_person_cred_hist_length, que representa la duración del historial crediticio de un cliente, expresada en años.

Distribución por duración del historial crediticio (cb_person_cred_hist_length)

Esta variable tiene 29 valores distintos, que van desde 2 a 30 años. La trataremos como una variable continua y la discretizaremos usando cuantiles.

Del cuadro anterior se pueden extraer varias observaciones. Primero, más del 56% de los prestatarios tienen un historial crediticio de cuatro años o menos, lo que indica que una gran proporción de los clientes en el conjunto de datos tienen historiales crediticios relativamente cortos.

En segundo lugar, la tasa de incumplimiento parece bastante estable en todos los intervalos, rondando el 21%. Dicho esto, los prestatarios con historiales crediticios más cortos tienden a exhibir un comportamiento ligeramente más riesgoso que aquellos con historiales crediticios más largos, como se refleja en sus tasas de incumplimiento más altas.

Distribución por defecto anterior (cb_person_default_on_file)

Esta variable indica si el prestatario ha incumplido previamente un préstamo. Por lo tanto, proporciona información valiosa sobre el comportamiento crediticio pasado del cliente.

Tiene dos valores posibles:

Y: el prestatario ha incumplido en el pasado N: el prestatario nunca ha incumplido

En este conjunto de datos, más del 80% de los prestatarios no tienen antecedentes de incumplimiento, lo que sugiere que la mayoría de los clientes han mantenido un historial de pago satisfactorio.

Sin embargo, surge una clara diferencia en el riesgo entre los dos grupos. Los prestatarios con un historial previo de incumplimiento son significativamente más riesgosos, con una tasa de incumplimiento de alrededor del 38%, en comparación con alrededor del 18% para los prestatarios que nunca han incumplido.

Este resultado es consistente con lo que se observa comúnmente en los modelos de riesgo crediticio: el comportamiento de pago pasado es a menudo uno de los predictores más sólidos del incumplimiento futuro.

Distribución por edad

La presencia de la variable edad en este conjunto de datos indica que los préstamos se otorgan a prestatarios individuales (clientes minoristas) en lugar de a entidades corporativas. Para analizar mejor esta variable, agrupamos a los prestatarios en intervalos de edad basados ​​en cuartiles.

El conjunto de datos incluye prestatarios de una amplia gama de edades. Sin embargo, la distribución está fuertemente sesgada hacia las personas más jóvenes: más del 70% de los prestatarios tienen menos de 30 años.

El análisis de las tasas de incumplimiento entre los grupos de edad revela que el mayor riesgo se concentra en el primer cuartil, seguido del segundo cuartil. En otras palabras, los prestatarios más jóvenes parecen ser el segmento más riesgoso en este conjunto de datos.

Distribución por Ingresos Anuales

Los ingresos anuales de los prestatarios en este conjunto de datos oscilan entre $ 4 000 y $ 6 000 000. Para analizar su relación con el riesgo de impago, dividimos la renta en cuatro intervalos basados ​​en cuartiles.

Los resultados muestran que las tasas de incumplimiento más altas se concentran entre los prestatarios con los ingresos más bajos, particularmente en el primer cuartil ($4,000–$385,00) y el segundo cuartil ($385,00–$55,000).

A medida que aumentan los ingresos, la tasa de morosidad disminuye gradualmente. Los prestatarios del tercer cuartil ($55 000 a $792 000) y del cuarto cuartil ($792 000 a $600 000) exhiben tasas de incumplimiento notablemente más bajas.

En general, este patrón sugiere una relación inversa entre el ingreso anual y el riesgo de incumplimiento, lo cual es consistente con las expectativas estándar de riesgo crediticio: los prestatarios con ingresos más altos generalmente tienen mayor capacidad de pago y estabilidad financiera, lo que los hace menos propensos a incumplir.

Distribución por propiedad de vivienda

Esta variable describe el estado de la vivienda del prestatario. Las categorías incluyen ALQUILER (inquilino), HIPOTECA (propietario de vivienda con hipoteca), PROPIO (propietario de vivienda sin hipoteca) y OTROS (otros arreglos de vivienda).

En este conjunto de datos, aproximadamente el 50% de los prestatarios son inquilinos, el 40% son propietarios de viviendas con una hipoteca, el 8% son propietarios absolutos de su vivienda y alrededor del 2% entran en la categoría "OTROS".

El análisis revela que las tasas de incumplimiento más altas se observan entre los inquilinos (RENT) y los prestatarios clasificados como “OTROS”. Por el contrario, los propietarios de viviendas sin hipoteca (PROPIOS) presentan las tasas de impago más bajas, seguidos de los prestatarios con hipotecas (HIPOTECA).

Distribución por persona duración del empleo person_emp_length

Esta variable mide la duración del empleo del prestatario en años. Para analizar su relación con el riesgo de incumplimiento, los prestatarios se agrupan en cuatro intervalos basados ​​en cuartiles: el primer cuartil (0 a 2 años), el segundo cuartil (2 a 4 años), el tercer cuartil (4 a 7 años) y el cuarto cuartil (7 años o más).

El análisis muestra que las tasas de incumplimiento más altas se concentran entre los prestatarios con los historiales laborales más cortos, particularmente aquellos en el primer cuartil (0 a 2 años) y el segundo cuartil (2 a 4 años).

A medida que aumenta la duración del empleo, la tasa de incumplimiento tiende a disminuir. Los prestatarios del tercer cuartil (de 4 a 7 años) y del cuarto cuartil (de 7 años o más) presentan tasas de incumplimiento más bajas.

En general, este patrón sugiere una relación inversa entre la duración del empleo y el riesgo de incumplimiento, lo que indica que los prestatarios con historiales laborales más prolongados pueden beneficiarse de una mayor estabilidad de ingresos y seguridad financiera, lo que reduce su probabilidad de incumplimiento.

Distribución por intención de préstamo

Esta variable categórica describe el propósito del préstamo solicitado por el prestatario. Las categorías incluyen EDUCACIÓN, MÉDICA, VENTURA (emprendimiento), PERSONAL, CONSOLIDACIÓN DE DEUDA y MEJORA DEL HOGAR.

El número de prestatarios está bastante equilibrado entre los diferentes propósitos de los préstamos, con una proporción ligeramente mayor de préstamos utilizados para educación (EDUCACIÓN) y gastos médicos (MÉDICOS).

Sin embargo, el análisis revela diferencias notables en el riesgo entre categorías. Los prestatarios que buscan préstamos para consolidación de deuda (DEBTCONSOLIDATION) y fines médicos (MEDICAL) exhiben tasas de incumplimiento más altas. Por el contrario, los préstamos destinados a educación (EDUCATION) y actividades empresariales (VENTURE) se asocian con tasas de incumplimiento más bajas.

En general, estos resultados sugieren que el propósito del préstamo puede ser un indicador de riesgo importante, ya que diferentes necesidades de financiamiento pueden reflejar diferentes niveles de estabilidad financiera y capacidad de pago.

Distribución por grado de préstamo

Esta variable categórica representa la calificación del préstamo asignada a cada prestatario, generalmente basada en una evaluación de su perfil de riesgo crediticio. Las calificaciones van de la A a la G, donde A corresponde a los préstamos de menor riesgo y G a los préstamos de mayor riesgo.

En este conjunto de datos, a más del 80% de los prestatarios se les asignan calificaciones A, B o C, lo que indica que la mayoría de los préstamos se consideran de riesgo relativamente bajo. En contraste, los grados D, E, F y G corresponden a prestatarios con mayor riesgo crediticio, y estas categorías representan una proporción mucho menor de las observaciones.

La distribución de las tasas de incumplimiento entre los grados muestra un patrón claro: la tasa de incumplimiento aumenta a medida que se deteriora la calificación del préstamo. En otras palabras, los prestatarios con calificaciones crediticias más bajas tienden a presentar mayores probabilidades de incumplimiento.

Este resultado es consistente con el propósito del propio sistema de calificación, ya que las calificaciones de los préstamos están diseñadas para resumir la solvencia crediticia del prestatario y el nivel de riesgo asociado.

Distribución por monto del préstamo

Esta variable representa el monto del préstamo solicitado por el prestatario. En este conjunto de datos, los montos de los préstamos oscilan entre $500 y $35 000, lo que corresponde a préstamos de consumo relativamente pequeños.

El análisis de las tasas de incumplimiento en los cuartiles muestra que el mayor riesgo se concentra entre los prestatarios en el rango superior de montos de préstamo, particularmente en el cuarto cuartil ($20 000 a $35 000), donde las tasas de incumplimiento son más altas.

Distribución por tipo de interés del préstamo (loan_int_rate)

Esta variable representa la tasa de interés aplicada al préstamo otorgado al prestatario. En este conjunto de datos, las tasas de interés oscilan entre el 5% y el 24%.

Para analizar la relación entre las tasas de interés y el riesgo de incumplimiento, agrupamos las observaciones en cuartiles. Los resultados muestran que las tasas de incumplimiento más altas se concentran en el rango superior de tasas de interés, particularmente en el cuarto cuartil (aproximadamente 13%-24%).

Distribución por porcentaje de ingresos de préstamos

Esta variable mide el porcentaje de los ingresos anuales de un prestatario destinado al pago del préstamo. Indica la carga financiera asociada con el préstamo en relación con los ingresos del prestatario.

El análisis muestra que las tasas de incumplimiento más altas se concentran en el cuartil superior, donde los prestatarios asignan entre el 20% y el 100% de sus ingresos al pago de préstamos.

Conclusión

En este análisis, hemos descrito cada una de las 12 variables del conjunto de datos. Este paso exploratorio nos permitió desarrollar una comprensión clara de los datos y resumir rápidamente sus características clave en la introducción.

En el pasado, este tipo de análisis solía llevar mucho tiempo y normalmente requería la colaboración de varios científicos de datos para realizar la exploración estadística y producir el informe final. Si bien las interpretaciones de diferentes variables a veces pueden parecer repetitivas, a menudo se requiere documentación tan detallada en entornos regulados, particularmente en campos como el modelado de riesgo crediticio.

Hoy, sin embargo, el auge de la inteligencia artificial está transformando este flujo de trabajo. Tareas que antes requerían varios días de trabajo ahora se pueden completar en menos de 30 minutos, bajo la supervisión de un estadístico o científico de datos. En este escenario, el papel del experto pasa de realizar manualmente el análisis a guiar el proceso, validar los resultados y garantizar su confiabilidad.

En la práctica, es posible diseñar dos agentes de IA especializados en esta etapa del flujo de trabajo. El primer agente ayuda con la preparación de datos y la construcción del conjunto de datos, mientras que el segundo realiza el análisis exploratorio y genera el informe descriptivo presentado en este artículo.

Hace varios años ya se recomendaba automatizar estas tareas siempre que fuera posible. En esta publicación, las tablas utilizadas a lo largo del análisis se generaron automáticamente usando las funciones de Python presentadas al final de este artículo.

En el próximo artículo, llevaremos el análisis un paso más allá al explorar el tratamiento de variables, detectar y manejar valores atípicos, analizar las relaciones entre variables y realizar una selección inicial de características.

Créditos de imagen

Todas las imágenes y visualizaciones de este artículo fueron creadas por el autor utilizando Python (pandas, matplotlib, seaborn y plotly) y Excel, a menos que se indique lo contrario.

Referencias

[1]Lorenzo Beretta y Alessandro Santaniello.
Algoritmos de imputación del vecino más cercano: una evaluación crítica.
Biblioteca Nacional de Medicina, 2016.

[2]Consultoría Nexialog.
Traitement des données manquantes dans le milieu bancaire.
Documento de trabajo, 2022.

[3]John T. Hancock y Taghi M. Khoshgoftaar.
Encuesta sobre datos categóricos para redes neuronales.
Revista de Big Data, 7(28), 2020.

[4]Melissa J. Azur, Elizabeth A. Stuart, Constantine Frangakis y Philip J. Leaf.
Imputación múltiple por ecuaciones encadenadas: ¿qué es y cómo funciona?
Revista internacional de métodos de investigación psiquiátrica, 2011.

[5]Majid Sarmad.
Análisis sólido de datos para diseños experimentales factoriales: métodos y software mejorados.
Departamento de Ciencias Matemáticas, Universidad de Durham, Inglaterra, 2006.

[6]Daniel J. Stekhoven y Peter Bühlmann.
MissForest: imputación de valores perdidos no paramétricos para datos de tipo mixto. Bioinformática, 2011.

[7]Supriyanto Wibisono, Anwar y Amin.
Detección de anomalías meteorológicas multivariadas mediante el algoritmo de agrupamiento DBSCAN.
Revista de Física: Serie de conferencias, 2021.

Datos y licencias

El conjunto de datos utilizado en este artículo tiene la licencia Creative Commons Attribution 4.0 International (CC BY 4.0).

Esta licencia permite a cualquier persona compartir y adaptar el conjunto de datos para cualquier propósito, incluido el uso comercial, siempre que se proporcione la atribución adecuada a la fuente.

Para obtener más detalles, consulte el texto de la licencia oficial: CC0: Dominio público.

Descargo de responsabilidad

Cualquier error o inexactitud restante es responsabilidad del autor. Se aceptan comentarios y correcciones.

Códigos

importar pandas como pd al escribir import Opcional, Unión def build_default_summary( df: pd.DataFrame, categoría_col: str, default_col: str, categoría_label: Opcional[str] = Ninguno, include_na: bool = False, sort_by: str = "count", ascendente: bool = False,) -> pd.DataFrame: """ Construye un cuadro de síntesis para una variable catégorielle. Parámetros ———- df: pd.DataFrame DataFrame source.category_col: str Nombre de la variable catégorielle. default_col: str Las columnas binarias indican el valor predeterminado (0/1 o booléen): bool, default=False. Es cierto, conserve los valores manquantes como sort_by: str, default="count" Colonne de tri logique parmi {"count", "defaults", "prop", "default_rate", "category"}. ascending: bool, default=False Retour —— pd.DataFrame Tableau prêt à exporter. df.columns: rise KeyError(f"La columna catégorielle '{category_col}' es introuvable.") if default_col no está en df.columns: rise KeyError(f"La columna défaut '{default_col}' es introuvable.") data = df[[category_col, default_col]].copy() # Validación mínima sobre el cible # On convertit bool -> entero; sinon on supuesto 0/1 documentado if pd.api.types.is_bool_dtype(data[default_col]): data[default_col] = data[default_col].astype(int) # Gestión de NA de la variable catégorielle if include_na: data[category_col] = data[category_col].astype("object").fillna("Missing") else: data = datos[datos[categoría_col].notna()].copia() agrupados = ( data.groupby(categoría_col, dropna=False)[default_col] .agg(count="size", defaults="sum") .reset_index() ) total_obs = agrupados["count"].sum() total_def = agrupados["defaults"].sum() agrupados["prop"] = agrupados["count"] / total_obs si total_obs > 0 else 0.0 agrupado["default_rate"] = agrupado["defaults"] / agrupado["count"] sort_mapping = { "count": "count", "defaults": "defaults", "prop": "prop", "default_rate": "default_rate", "category": categor_col, } si sort_by no está en sort_mapping: aumentar ValueError( "sort_by debe ser parmi {'count', 'defaults', 'prop', 'default_rate', 'category'}." ) grouped = grouped.sort_values(sort_mapping[sort_by], ascending=ascending).reset_index(drop=True) total_row = pd.DataFrame( { categor_col: ["Total"], "count": [total_obs], "defaults": [total_def], "prop": [1.0 si total_obs > 0 más 0.0], "default_rate": [total_def / total_obs si total_obs > 0 más 0.0], } ) resumen = pd.concat([agrupado, total_row], ignore_index=True) resumen = resumen.rename( columnas={ categoría_col: categoría_label o categoría_col, "count": "Nb de obs", "defaults": "Nb def", "prop": "Prop", "default_rate": "Tasa predeterminada", } ) resumen = resumen[[category_label o categoría_col, "Nb de obs", "Prop", "Nb def", "Tasa predeterminada"]] return resumen def export_summary_to_excel( resumen: pd.DataFrame, ruta_salida: cadena, nombre_hoja: cadena = "Resumen", título: cadena = "Todos los perímetros", ) -> Ninguno: """ Exporte la tabla de síntesis a un archivo Excel con configuración. Necesita el motor xlsxwriter. """ con pd.ExcelWriter(output_path, motor="xlsxwriter") como escritor: # libro de trabajo = escritor.libro hoja de trabajo = workbook.add_worksheet(sheet_name) nrows, ncols = resumen.shape total_excel_row = 2 + nrows # +1 implícito Excel car index 0-based côté xlsxwriter pour set_row # Detalle: # línea 0: título fusionado # línea 2: encabezado # données comienza la línea 3 (Excel visual), más xlsxwriter manipula en base 0 # ——– Formatos ——– border_color = "#4F4F4F" header_bg = "#D9EAF7" title_bg = "#CFE2F3" total_bg = "#D9D9D9" white_bg = "#FFFFFF" title_fmt = workbook.add_format({ "bold": True, "align": "center", "valign": "vcenter", "font_size": 14, "border": 1, "bg_color": title_bg, }) header_fmt = workbook.add_format({ "bold": True, "align": "center", "valign": "vcenter", "border": 1, "bg_color": header_bg, }) text_fmt = workbook.add_format({ "border": 1, "align": "left", "valign": "vcenter", "bg_color": white_bg, }) int_fmt = workbook.add_format({ "border": 1, "align": "center", "valign": "vcenter", "num_format": "# ##0", "bg_color": white_bg, }) pct_fmt = workbook.add_format({ "border": 1, "align": "center", "valign": "vcenter", "num_format": "0.00%", "bg_color": white_bg, }) total_text_fmt = workbook.add_format({ "bold": True, "border": 1, "align": "center", "valign": "vcenter", "bg_color": total_bg, }) total_int_fmt = workbook.add_format({ "negrita": Verdadero, "borde": 1, "align": "centro", "valign": "vcenter", "num_format": "# ##0", "bg_color": total_bg, }) total_pct_fmt = workbook.add_format({ "negrita": Verdadero, "borde": 1, "align": "centro", "valign": "vcenter", "num_format": "0.00%", "bg_color": total_bg, }) # ——– Título fusionado ——– worksheet.merge_range(0, 0, 0, ncols – 1, title, title_fmt) # ——– Encabezado ——– worksheet.set_row(2, 28) para col_idx, col_name en enumerate(summary.columns): worksheet.write(1, col_idx, col_name, header_fmt) # ——– Largeurs de colonnes ——– column_widths = { 0: 24, # catégorie 1: 14, # Nb of obs 2: 12, # Nb def 3: 10, # Prop 4: 14, # Default rate } para col_idx in range(ncols): worksheet.set_column(col_idx, col_idx, column_widths.get(col_idx, 15)) # ——– Colocar en forma celular por celular ——– last_row_idx = nrows – 1 for row_idx in range(nrows): excel_row = 2 + row_idx # données à partir de la línea 3 (basado en 0) xlsxwriter) is_total = row_idx == last_row_idx for col_idx, col_name in enumerate(summary.columns): valor = resumen.iloc[row_idx, col_idx] if col_idx == 0: fmt = total_text_fmt if is_total else text_fmt elif col_name in ["Nb of obs", "Nb def"]: fmt = total_int_fmt if is_total else int_fmt elif col_name in ["Prop", "Tasa predeterminada"]: fmt = total_pct_fmt if is_total else pct_fmt else: fmt = total_text_fmt if is_total else text_fmt worksheet.write(excel_row, col_idx, value, fmt) # Optionnel: figura el encabezado #worksheet.freeze_panes(3, 1) worksheet.set_default_row(24) def generate_categorical_report_excel( df: pd.DataFrame, categoría_col: cadena, default_col: cadena, ruta_salida: cadena, nombre_hoja: cadena = "Resumen", título: cadena = "Todos los perímetros", etiqueta_categoría: Opcional[cadena] = Ninguno, include_na: bool = Falso, sort_by: str = "count", ascending: bool = False, ) -> pd.DataFrame: """ 1. Calcular la tabla 2. Exportar a Excel 3. Enviar además el DataFrame recapitulativo """ resumen = build_default_summary( df=df, categoría_col=categoría_col, default_col=default_col, categoría_label=etiqueta_categoría, incluir_na=incluir_na, ordenar_por=ordenar_por, ascendente=ascendente, ) export_summary_to_excel( resumen=summary, ruta_salida=ruta_salida, nombre_hoja=nombre_hoja, título=título, ) devolver resumen def discretize_variable_by_quartiles( df: pd.DataFrame, variable: str, new_var: str | Ninguno = Ninguno) -> pd.DataFrame: """ Discretiza una variable continua en cuatro intervalos según sus cuartiles. La función calcula Q1, Q2 (mediana) y Q3 de la variable seleccionada y crea cuatro contenedores correspondientes a los siguientes intervalos: ]min ; Q1], ]Q1 ; Q2], ]Q2 ; Q3], ]Q3 ; max] Parámetros ———- df : pd.DataFrame Entrada marco de datos que contiene la variable a discretizar. variable: str Nombre de la variable continua a discretizar. new_var: str, opcional Nombre de la nueva variable categórica creada. Si no hay ninguno, se usa el nombre "_quartile" Devuelve ——- pd.DataFrame Una copia del marco de datos con la nueva variable categórica basada en cuartiles """ # Crea una copia del marco de datos para evitar modificar el conjunto de datos original. proporcionado para la nueva variable, cree uno automáticamente si new_var es Ninguno: new_var = f"{variable}_quartile" # Calcular los cuartiles de la variable q1, q2, q3 = data[variable].quantile([0.25, 0.50, 0.75]) # Recuperar los valores mínimo y máximo de la variable vmin = data[variable].min() vmax = data[variable].max() # Definir los bordes del contenedor # Un pequeño épsilon se resta del valor mínimo para garantizar que esté incluido bins = [vmin – 1e-9, q1, q2, q3, vmax] # Definir etiquetas legibles por humanos para cada intervalo etiquetas = [ f"]{vmin:.2f} ; {q1:.2f}]", f"]{q1:.2f} ; {q2:.2f}]", f"]{q2:.2f} ; {q3:.2f}]", f"]{q3:.2f} ; {vmax:.2f}]", ] # Utilice pandas.cut para asignar cada observación a un intervalo basado en cuartiles data[new_var] = pd.cut( data[variable], bins=bins, label=labels, include_lowest=True ) # Devuelva el marco de datos con los nuevos datos de retorno de la variable discretizada

Ejemplo de aplicación de una variable continua

# Distribución por edad (persona_edad) # Discretizar la variable en cuartiles df_with_age_bins = create_quartile_bins( df, variable="person_age", new_var="age_quartile" ) suma