LLMS + PANDAS: Cómo uso la IA generativa para generar resúmenes de marco de datos PANDAS

conjuntos de datos y están buscando ideas rápidas sin demasiada rutina manual, has venido al lugar correcto.

En 2025, los conjuntos de datos a menudo contienen millones de filas y cientos de columnas, lo que hace que el análisis manual sea imposible. Los modelos locales de lenguaje grande pueden transformar sus estadísticas de marco de datos sin procesar en informes pulidos y legibles en segundos, minutos en el peor de los casos. Este enfoque elimina el tedioso proceso de análisis de datos a mano y escribiendo informes ejecutivos, especialmente si la estructura de datos no cambia.

Pandas maneja el trabajo pesado de la extracción de datos, mientras que los LLM convierten sus salidas técnicas en informes presentables. Todavía deberá escribir funciones que extraen estadísticas clave de sus conjuntos de datos, pero es un esfuerzo único.

Esta guía asume que tiene Ollama instalado localmente. Si no lo hace, aún puede usar proveedores de terceros LLM, pero no explicaré cómo conectarse a sus API.

Tabla de contenido:

  • Introducción y exploración del conjunto de datos
  • La parte aburrida: extracción de estadísticas de resumen
  • La parte genial: trabajar con LLMS
  • Lo que podrías mejorar

Introducción y exploración del conjunto de datos

Para esta guía, estoy usando el Conjunto de datos de admisiones de MBA de Kaggle. Descárguelo si quieres seguir.

El conjunto de datos tiene licencia bajo el Licencia Apache 2.0lo que significa que puede usarlo libremente para proyectos personales y comerciales.

Para comenzar, necesitará algunas bibliotecas de Python instaladas en su sistema.

Imagen 1 – Bibliotecas y versiones de Python requeridas (Imagen del autor)

Una vez que tenga todo instalado, importe las bibliotecas necesarias en un nuevo script o un cuaderno:

import pandas as pd
from langchain_ollama import ChatOllama
from typing import Literal

Carga y preprocesamiento del conjunto de datos

Comience cargando el conjunto de datos con Pandas. Este fragmento carga el archivo CSV, imprime información básica sobre la forma del conjunto de datos y muestra cuántos valores faltantes existen en cada columna:

df = pd.read_csv("data/MBA.csv")

# Basic dataset info
print(f"Dataset shape: {df.shape}\n")
print("Missing value stats:")
print(df.isnull().sum())
print("-" * 25)
df.sample(5)
Imagen 2 – Estadísticas básicas del conjunto de datos (imagen del autor)

Dado que la limpieza de datos no es el foco principal de este artículo, mantendré el preprocesamiento mínimo. El conjunto de datos solo tiene un par de valores faltantes que necesitan atención:

df["race"] = df["race"].fillna("Unknown")
df["admission"] = df["admission"].fillna("Deny")

¡Eso es todo! Veamos cómo pasar de esto a un informe significativo a continuación.

La parte aburrida: extracción de estadísticas de resumen

Incluso con todos los avances en la capacidad y la disponibilidad de IA, probablemente no desee enviar todo su conjunto de datos a un proveedor de LLM. Hay un par de buenas razones por las cuales.

Podría consumir demasiados tokensque se traduce directamente a costos más altos. Procesar conjuntos de datos grandes puede Tomar mucho tiempoespecialmente cuando está ejecutando modelos localmente en su propio hardware. También podría estar lidiando con datos confidenciales Eso no debería dejar su organización.

Algún trabajo manual sigue siendo el camino a seguir.

Este enfoque requiere que escriba una función que extraiga elementos clave y estadísticas de su marco de datos PANDAS. Tendrá que escribir esta función desde cero para diferentes conjuntos de datos, pero la idea central transfiere fácilmente entre los proyectos.

El get_summary_context_message() La función toma un marco de datos y devuelve una cadena de múltiples líneas formateadas con un resumen detallado. Esto es lo que incluye:

  • Recuento total de aplicaciones y distribución de género
  • Desglose de solicitantes internacionales vs nacionales
  • Estadísticas de cuartil de puntaje de GPA y GMAT
  • Tasas de admisión por especialización académica (ordenadas por tarifa)
  • Tasas de admisión por industria laboral (las 8 industrias principales)
  • Análisis de experiencia laboral con desgloses categóricos
  • Insights clave que destacan categorías de alto rendimiento

Aquí está el código fuente completo para la función:

def get_summary_context_message(df: pd.DataFrame) -> str:
    """
    Generate a comprehensive summary report of MBA admissions dataset statistics.
    
    This function analyzes MBA application data to provide detailed statistics on
    applicant demographics, academic performance, professional backgrounds, and
    admission rates across various categories. The summary includes gender and
    international status distributions, GPA and GMAT score statistics, admission
    rates by academic major and work industry, and work experience impact analysis.
    
    Parameters
    ----------
    df : pd.DataFrame
        DataFrame containing MBA admissions data with the following expected columns:
        - 'gender', 'international', 'gpa', 'gmat', 'major', 'work_industry', 'work_exp', 'admission'
    
    Returns
    -------
    str
        A formatted multi-line string containing comprehensive MBA admissions
        statistics.
    """
    # Basic application statistics
    total_applications = len(df)

    # Gender distribution
    gender_counts = df["gender"].value_counts()
    male_count = gender_counts.get("Male", 0)
    female_count = gender_counts.get("Female", 0)

    # International status
    international_count = (
        df["international"].sum()
        if df["international"].dtype == bool
        else (df["international"] == True).sum()
    )

    # GPA statistics
    gpa_data = df["gpa"].dropna()
    gpa_avg = gpa_data.mean()
    gpa_25th = gpa_data.quantile(0.25)
    gpa_50th = gpa_data.quantile(0.50)
    gpa_75th = gpa_data.quantile(0.75)

    # GMAT statistics
    gmat_data = df["gmat"].dropna()
    gmat_avg = gmat_data.mean()
    gmat_25th = gmat_data.quantile(0.25)
    gmat_50th = gmat_data.quantile(0.50)
    gmat_75th = gmat_data.quantile(0.75)

    # Major analysis - admission rates by major
    major_stats = []
    for major in df["major"].unique():
        major_data = df[df["major"] == major]
        admitted = len(major_data[major_data["admission"] == "Admit"])
        total = len(major_data)
        rate = (admitted / total) * 100
        major_stats.append((major, admitted, total, rate))

    # Sort by admission rate (descending)
    major_stats.sort(key=lambda x: x[3], reverse=True)

    # Work industry analysis - admission rates by industry
    industry_stats = []
    for industry in df["work_industry"].unique():
        if pd.isna(industry):
            continue
        industry_data = df[df["work_industry"] == industry]
        admitted = len(industry_data[industry_data["admission"] == "Admit"])
        total = len(industry_data)
        rate = (admitted / total) * 100
        industry_stats.append((industry, admitted, total, rate))

    # Sort by admission rate (descending)
    industry_stats.sort(key=lambda x: x[3], reverse=True)

    # Work experience analysis
    work_exp_data = df["work_exp"].dropna()
    avg_work_exp_all = work_exp_data.mean()

    # Work experience for admitted students
    admitted_students = df[df["admission"] == "Admit"]
    admitted_work_exp = admitted_students["work_exp"].dropna()
    avg_work_exp_admitted = admitted_work_exp.mean()

    # Work experience ranges analysis
    def categorize_work_exp(exp):
        if pd.isna(exp):
            return "Unknown"
        elif exp < 2:
            return "0-1 years"
        elif exp < 4:
            return "2-3 years"
        elif exp < 6:
            return "4-5 years"
        elif exp < 8:
            return "6-7 years"
        else:
            return "8+ years"

    df["work_exp_category"] = df["work_exp"].apply(categorize_work_exp)
    work_exp_category_stats = []

    for category in ["0-1 years", "2-3 years", "4-5 years", "6-7 years", "8+ years"]:
        category_data = df[df["work_exp_category"] == category]
        if len(category_data) > 0:
            admitted = len(category_data[category_data["admission"] == "Admit"])
            total = len(category_data)
            rate = (admitted / total) * 100
            work_exp_category_stats.append((category, admitted, total, rate))

    # Build the summary message
    summary = f"""MBA Admissions Dataset Summary (2025)
    
Total Applications: {total_applications:,} people applied to the MBA program.

Gender Distribution:
- Male applicants: {male_count:,} ({male_count/total_applications*100:.1f}%)
- Female applicants: {female_count:,} ({female_count/total_applications*100:.1f}%)

International Status:
- International applicants: {international_count:,} ({international_count/total_applications*100:.1f}%)
- Domestic applicants: {total_applications-international_count:,} ({(total_applications-international_count)/total_applications*100:.1f}%)

Academic Performance Statistics:

GPA Statistics:
- Average GPA: {gpa_avg:.2f}
- 25th percentile: {gpa_25th:.2f}
- 50th percentile (median): {gpa_50th:.2f}
- 75th percentile: {gpa_75th:.2f}

GMAT Statistics:
- Average GMAT: {gmat_avg:.0f}
- 25th percentile: {gmat_25th:.0f}
- 50th percentile (median): {gmat_50th:.0f}
- 75th percentile: {gmat_75th:.0f}

Major Analysis - Admission Rates by Academic Background:"""

    for major, admitted, total, rate in major_stats:
        summary += (
            f"\n- {major}: {admitted}/{total} admitted ({rate:.1f}% admission rate)"
        )

    summary += (
        "\n\nWork Industry Analysis - Admission Rates by Professional Background:"
    )

    # Show top 8 industries by admission rate
    for industry, admitted, total, rate in industry_stats[:8]:
        summary += (
            f"\n- {industry}: {admitted}/{total} admitted ({rate:.1f}% admission rate)"
        )

    summary += "\n\nWork Experience Impact on Admissions:\n\nOverall Work Experience Comparison:"
    summary += (
        f"\n- Average work experience (all applicants): {avg_work_exp_all:.1f} years"
    )
    summary += f"\n- Average work experience (admitted students): {avg_work_exp_admitted:.1f} years"

    summary += "\n\nAdmission Rates by Work Experience Range:"
    for category, admitted, total, rate in work_exp_category_stats:
        summary += (
            f"\n- {category}: {admitted}/{total} admitted ({rate:.1f}% admission rate)"
        )

    # Key insights
    best_major = major_stats[0]
    best_industry = industry_stats[0]

    summary += "\n\nKey Insights:"
    summary += (
        f"\n- Highest admission rate by major: {best_major[0]} at {best_major[3]:.1f}%"
    )
    summary += f"\n- Highest admission rate by industry: {best_industry[0]} at {best_industry[3]:.1f}%"

    if avg_work_exp_admitted > avg_work_exp_all:
        summary += f"\n- Admitted students have slightly more work experience on average ({avg_work_exp_admitted:.1f} vs {avg_work_exp_all:.1f} years)"
    else:
        summary += "\n- Work experience shows minimal difference between admitted and all applicants"

    return summary

Una vez que haya definido la función, simplemente llame e imprima los resultados:

print(get_summary_context_message(df))
Imagen 3 – Hallazgos y estadísticas extraídas del conjunto de datos (imagen por autor)

Ahora pasemos a la parte divertida.

La parte genial: trabajar con LLMS

Aquí es donde las cosas se ponen interesantes y su trabajo manual de extracción de datos vale la pena.

Función a ayuda de Python para trabajar con LLMS

Si tiene hardware decente, le recomiendo usar LLM locales para tareas simples como esta. Yo uso Ollama y la última versión del Modelo mistral para el procesamiento real de LLM.

Imagen 4 – Modelos Ollama disponibles (Imagen del autor)

Si desea usar algo como ChatGPT a través de la API de Operai, aún puede hacerlo. Solo deberá modificar la función a continuación para configurar su clave API y devolver la instancia apropiada de Langchain.

Independientemente de la opción que elija, una llamada a get_llm() con un mensaje de prueba no debe devolver un error:

def get_llm(model_name: str = "mistral:latest") -> ChatOllama:
    """
    Create and configure a ChatOllama instance for local LLM inference.
    
    This function initializes a ChatOllama client configured to connect to a
    local Ollama server. The client is set up with deterministic output
    (temperature=0) for consistent responses across multiple calls with the
    same input.
    
    Parameters
    ----------
    model_name : str, optional
        The name of the Ollama model to use for chat completions.
        Must be a valid model name that is available on the local Ollama
        installation. Default is "mistral:latest".
    
    Returns
    -------
    ChatOllama
        A configured ChatOllama instance ready for chat completions.
    """
    return ChatOllama(
        model=model_name, base_url="http://localhost:11434", temperature=0
    )


print(get_llm().invoke("test").content)
Imagen 5 – Mensaje de prueba LLM (Imagen por autor)

Aviso de resumen

Aquí es donde puede ser creativo y escribir instrucciones ultra específicas para su LLM. He decidido mantener las cosas ligeras para fines de demostración, pero no dude en experimentar aquí.

No hay un solo mensaje correcto o incorrecto.

Hagas lo que hagas, asegúrate de incluir los argumentos de formato utilizando soportes rizados: estos valores se llenarán dinámicamente más adelante:

SUMMARIZE_DATAFRAME_PROMPT = """
You are an expert data analyst and data summarizer. Your task is to take in complex datasets
and return user-friendly descriptions and findings.

You were given this dataset:
- Name: {dataset_name}
- Source: {dataset_source}

This dataset was analyzed in a pipeline before it was given to you.
These are the findings returned by the analysis pipeline:

<context>
{context}
</context>

Based on these findings, write a detailed report in {report_format} format.
Give the report a meaningful title and separate findings into sections with headings and subheadings.
Output only the report in {report_format} and nothing else.

Report:
"""

Resumen de la función de pitón

Con el aviso y el get_llm() Funciones declaradas, lo único que queda es conectar los puntos. El get_report_summary() La función toma argumentos que llenarán los marcadores de posición de formato en el aviso, luego invoca el LLM con ese indicador para generar un informe.

Puede elegir entre los formatos Markdown o HTML:

def get_report_summary(
    dataset: pd.DataFrame,
    dataset_name: str,
    dataset_source: str,
    report_format: Literal["markdown", "html"] = "markdown",
) -> str:
    """
    Generate an AI-powered summary report from a pandas DataFrame.
    
    This function analyzes a dataset and generates a comprehensive summary report
    using a large language model (LLM). It first extracts statistical context
    from the dataset, then uses an LLM to create a human-readable report in the
    specified format.
    
    Parameters
    ----------
    dataset : pd.DataFrame
        The pandas DataFrame to analyze and summarize.
    dataset_name : str
        A descriptive name for the dataset that will be included in the
        generated report for context and identification.
    dataset_source : str
        Information about the source or origin of the dataset.
    report_format : {"markdown", "html"}, optional
        The desired output format for the generated report. Options are:
        - "markdown" : Generate report in Markdown format (default)
        - "html" : Generate report in HTML format
    
    Returns
    -------
    str
        A formatted summary report.
    
    """
    context_message = get_summary_context_message(df=dataset)
    prompt = SUMMARIZE_DATAFRAME_PROMPT.format(
        dataset_name=dataset_name,
        dataset_source=dataset_source,
        context=context_message,
        report_format=report_format,
    )
    return get_llm().invoke(input=prompt).content

El uso de la función es sencillo: simplemente pase en el conjunto de datos, su nombre y fuente. El formato de informe predeterminado es Markdown:

md_report = get_report_summary(
    dataset=df, 
    dataset_name="MBA Admissions (2025)",
    dataset_source="https://www.kaggle.com/datasets/taweilo/mba-admission-dataset"
)
print(md_report)
Imagen 6 – Informe final en formato de Markdown (Imagen del autor)

El informe HTML es igual de detallado, pero podría usar algo de estilo. ¡Tal vez podrías pedirle al LLM que también lo maneje!

Imagen 7 – Informe final en formato HTML (imagen por autor)

Lo que podrías mejorar

Podría haber convertido esto fácilmente en una lectura de 30 minutos al optimizar cada detalle de la tubería, pero lo mantuve simple para fines de demostración. Sin embargo, no es necesario que pare (y no debería) detenerse aquí.

Estas son las cosas que puede mejorar para que esta tubería sea aún más poderosa:

  • Escriba una función que guarde el informe (Markdown o HTML) directamente al disco. De esta manera, puede automatizar todo el proceso y generar informes sobre un cronograma sin intervención manual.
  • En el aviso, Pídale al LLM que agregue el estilo CSS al informe HTML para que parezca más presentable. Incluso puede proporcionar los colores y las fuentes de la marca de su empresa para mantener la consistencia en todos sus informes de datos.
  • Expanda el indicador para seguir instrucciones más específicas. Es posible que desee informes que se centren en métricas comerciales específicas, sigan una plantilla en particular o incluyan recomendaciones basadas en los hallazgos.
  • Expandir el get_llm() función para que pueda Conecte tanto a Ollama como a otros proveedores Como OpenAi, Anthrope o Google. Esto le brinda flexibilidad para cambiar entre modelos locales y basados ​​en la nube según sus necesidades.
  • Hacer literalmente cualquier cosa en la función get_summary_context_message () ya que sirve como base para todos Datos de contexto proporcionados a la LLM. Aquí es donde puede ser creativo con la ingeniería de características, el análisis estadístico y las ideas de datos que importan para su caso de uso específico.

Espero que este ejemplo mínimo lo haya puesto en el camino correcto para automatizar sus propios flujos de trabajo de informes de datos.