From 52461374be734839601f3e726155653043c3912c Mon Sep 17 00:00:00 2001 From: Marta Date: Sat, 29 Nov 2025 12:54:17 +0100 Subject: [PATCH] lab completed --- lab-dw-aggregating.ipynb | 706 +++++++++++++++++++++++++++++++-------- 1 file changed, 559 insertions(+), 147 deletions(-) diff --git a/lab-dw-aggregating.ipynb b/lab-dw-aggregating.ipynb index fadd718..c14de15 100644 --- a/lab-dw-aggregating.ipynb +++ b/lab-dw-aggregating.ipynb @@ -1,165 +1,577 @@ { - "cells": [ - { - "cell_type": "markdown", - "id": "31969215-2a90-4d8b-ac36-646a7ae13744", - "metadata": { - "id": "31969215-2a90-4d8b-ac36-646a7ae13744" - }, - "source": [ - "# Lab | Data Aggregation and Filtering" - ] - }, - { - "cell_type": "markdown", - "id": "a8f08a52-bec0-439b-99cc-11d3809d8b5d", - "metadata": { - "id": "a8f08a52-bec0-439b-99cc-11d3809d8b5d" - }, - "source": [ - "In this challenge, we will continue to work with customer data from an insurance company. We will use the dataset called marketing_customer_analysis.csv, which can be found at the following link:\n", - "\n", - "https://raw.githubusercontent.com/data-bootcamp-v4/data/main/marketing_customer_analysis.csv\n", - "\n", - "This dataset contains information such as customer demographics, policy details, vehicle information, and the customer's response to the last marketing campaign. Our goal is to explore and analyze this data by first performing data cleaning, formatting, and structuring." - ] - }, + "cells": [ + { + "cell_type": "markdown", + "id": "31969215-2a90-4d8b-ac36-646a7ae13744", + "metadata": { + "id": "31969215-2a90-4d8b-ac36-646a7ae13744" + }, + "source": [ + "# Lab | Data Aggregation and Filtering" + ] + }, + { + "cell_type": "markdown", + "id": "a8f08a52-bec0-439b-99cc-11d3809d8b5d", + "metadata": { + "id": "a8f08a52-bec0-439b-99cc-11d3809d8b5d" + }, + "source": [ + "In this challenge, we will continue to work with customer data from an insurance company. We will use the dataset called marketing_customer_analysis.csv, which can be found at the following link:\n", + "\n", + "https://raw.githubusercontent.com/data-bootcamp-v4/data/main/marketing_customer_analysis.csv\n", + "\n", + "This dataset contains information such as customer demographics, policy details, vehicle information, and the customer's response to the last marketing campaign. Our goal is to explore and analyze this data by first performing data cleaning, formatting, and structuring." + ] + }, + { + "cell_type": "markdown", + "id": "9c98ddc5-b041-4c94-ada1-4dfee5c98e50", + "metadata": { + "id": "9c98ddc5-b041-4c94-ada1-4dfee5c98e50" + }, + "source": [ + "1. Create a new DataFrame that only includes customers who:\n", + " - have a **low total_claim_amount** (e.g., below $1,000),\n", + " - have a response \"Yes\" to the last marketing campaign." + ] + }, + { + "cell_type": "markdown", + "id": "b9be383e-5165-436e-80c8-57d4c757c8c3", + "metadata": { + "id": "b9be383e-5165-436e-80c8-57d4c757c8c3" + }, + "source": [ + "2. Using the original Dataframe, analyze:\n", + " - the average `monthly_premium` and/or customer lifetime value by `policy_type` and `gender` for customers who responded \"Yes\", and\n", + " - compare these insights to `total_claim_amount` patterns, and discuss which segments appear most profitable or low-risk for the company." + ] + }, + { + "cell_type": "markdown", + "id": "7050f4ac-53c5-4193-a3c0-8699b87196f0", + "metadata": { + "id": "7050f4ac-53c5-4193-a3c0-8699b87196f0" + }, + "source": [ + "3. Analyze the total number of customers who have policies in each state, and then filter the results to only include states where there are more than 500 customers." + ] + }, + { + "cell_type": "markdown", + "id": "b60a4443-a1a7-4bbf-b78e-9ccdf9895e0d", + "metadata": { + "id": "b60a4443-a1a7-4bbf-b78e-9ccdf9895e0d" + }, + "source": [ + "4. Find the maximum, minimum, and median customer lifetime value by education level and gender. Write your conclusions." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "f7af3323-cdbc-424c-b53f-f295d06fac92", + "metadata": {}, + "outputs": [ { - "cell_type": "markdown", - "id": "9c98ddc5-b041-4c94-ada1-4dfee5c98e50", - "metadata": { - "id": "9c98ddc5-b041-4c94-ada1-4dfee5c98e50" - }, - "source": [ - "1. Create a new DataFrame that only includes customers who:\n", - " - have a **low total_claim_amount** (e.g., below $1,000),\n", - " - have a response \"Yes\" to the last marketing campaign." - ] - }, + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Nombres de columnas limpiados (primeras 5):\n", + " unnamed:_0 customer state customer_lifetime_value response \\\n", + "0 0 DK49336 Arizona 4809.216960 No \n", + "1 1 KX64629 California 2228.525238 No \n", + "2 2 LZ68649 Washington 14947.917300 No \n", + "3 3 XL78013 Oregon 22332.439460 Yes \n", + "4 4 QA50777 Oregon 9025.067525 No \n", + "\n", + " coverage education effective_to_date employmentstatus gender ... \\\n", + "0 Basic College 2/18/11 Employed M ... \n", + "1 Basic College 1/18/11 Unemployed F ... \n", + "2 Basic Bachelor 2/10/11 Employed M ... \n", + "3 Extended College 1/11/11 Employed M ... \n", + "4 Premium Bachelor 1/17/11 Medical Leave F ... \n", + "\n", + " number_of_open_complaints number_of_policies policy_type policy \\\n", + "0 0.0 9 Corporate Auto Corporate L3 \n", + "1 0.0 1 Personal Auto Personal L3 \n", + "2 0.0 2 Personal Auto Personal L3 \n", + "3 0.0 2 Corporate Auto Corporate L3 \n", + "4 NaN 7 Personal Auto Personal L2 \n", + "\n", + " renew_offer_type sales_channel total_claim_amount vehicle_class \\\n", + "0 Offer3 Agent 292.800000 Four-Door Car \n", + "1 Offer4 Call Center 744.924331 Four-Door Car \n", + "2 Offer3 Call Center 480.000000 SUV \n", + "3 Offer2 Branch 484.013411 Four-Door Car \n", + "4 Offer1 Branch 707.925645 Four-Door Car \n", + "\n", + " vehicle_size vehicle_type \n", + "0 Medsize NaN \n", + "1 Medsize NaN \n", + "2 Medsize A \n", + "3 Medsize A \n", + "4 Medsize NaN \n", + "\n", + "[5 rows x 26 columns]\n" + ] + } + ], + "source": [ + "import pandas as pd\n", + "\n", + "url = \"https://raw.githubusercontent.com/data-bootcamp-v4/data/main/marketing_customer_analysis.csv\"\n", + "\n", + "df = pd.read_csv(url)\n", + "\n", + "\n", + "# Función de limpieza de nombres de columnas\n", + "def clean_column_names(dataframe):\n", + " cols = dataframe.columns\n", + " new_cols = []\n", + " for col in cols:\n", + " new_col = col.lower().replace(' ', '_')\n", + " new_cols.append(new_col)\n", + " dataframe.columns = new_cols\n", + " return dataframe\n", + "\n", + "# Limpiar los nombres de las columnas del DataFrame\n", + "df_clean = clean_column_names(df.copy())\n", + "\n", + "print(\"\\nNombres de columnas limpiados (primeras 5):\")\n", + "print(df_clean.head())" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "2bd33d9c-c3f4-441e-87ee-8674156c0776", + "metadata": {}, + "outputs": [ { - "cell_type": "markdown", - "id": "b9be383e-5165-436e-80c8-57d4c757c8c3", - "metadata": { - "id": "b9be383e-5165-436e-80c8-57d4c757c8c3" - }, - "source": [ - "2. Using the original Dataframe, analyze:\n", - " - the average `monthly_premium` and/or customer lifetime value by `policy_type` and `gender` for customers who responded \"Yes\", and\n", - " - compare these insights to `total_claim_amount` patterns, and discuss which segments appear most profitable or low-risk for the company." - ] + "name": "stdout", + "output_type": "stream", + "text": [ + "Index(['unnamed:_0', 'customer', 'state', 'customer_lifetime_value',\n", + " 'response', 'coverage', 'education', 'effective_to_date',\n", + " 'employmentstatus', 'gender', 'income', 'location_code',\n", + " 'marital_status', 'monthly_premium_auto', 'months_since_last_claim',\n", + " 'months_since_policy_inception', 'number_of_open_complaints',\n", + " 'number_of_policies', 'policy_type', 'policy', 'renew_offer_type',\n", + " 'sales_channel', 'total_claim_amount', 'vehicle_class', 'vehicle_size',\n", + " 'vehicle_type'],\n", + " dtype='object')\n" + ] }, { - "cell_type": "markdown", - "id": "7050f4ac-53c5-4193-a3c0-8699b87196f0", - "metadata": { - "id": "7050f4ac-53c5-4193-a3c0-8699b87196f0" - }, - "source": [ - "3. Analyze the total number of customers who have policies in each state, and then filter the results to only include states where there are more than 500 customers." + "data": { + "text/plain": [ + "array([9, 1, 2, 7, 4, 3, 6, 8, 5])" ] - }, + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "\n", + "print(df_clean.columns)\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "2b8b0174-f6a5-47b5-a468-30685440e717", + "metadata": {}, + "outputs": [ { - "cell_type": "markdown", - "id": "b60a4443-a1a7-4bbf-b78e-9ccdf9895e0d", - "metadata": { - "id": "b60a4443-a1a7-4bbf-b78e-9ccdf9895e0d" - }, - "source": [ - "4. Find the maximum, minimum, and median customer lifetime value by education level and gender. Write your conclusions." - ] - }, + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "--- DataFrame de Clientes Filtrados (Reclamo < $1000 y Respuesta 'Yes') ---\n", + "Total de clientes filtrados: 1399\n", + " total_claim_amount response\n", + "3 484.013411 Yes\n", + "8 739.200000 Yes\n", + "15 547.200000 Yes\n", + "19 19.575683 Yes\n", + "27 60.036683 Yes\n" + ] + } + ], + "source": [ + "# Crear un nuevo DataFrame con clientes específicos\n", + "\n", + "# Definir el umbral de reclamo bajo\n", + "umbral_reclamo = 1000\n", + "\n", + "# Filtrar a los clientes: reclamo bajo Y respuesta \"Yes\"\n", + "df_clientes_filtrados = df_clean[\n", + " (df_clean['total_claim_amount'] < umbral_reclamo) &\n", + " (df_clean['response'] == 'Yes')\n", + "]\n", + "\n", + "print(\"\\n--- DataFrame de Clientes Filtrados (Reclamo < $1000 y Respuesta 'Yes') ---\")\n", + "print(f\"Total de clientes filtrados: {df_clientes_filtrados.shape[0]}\")\n", + "print(df_clientes_filtrados[['total_claim_amount', 'response']].head())" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "01d156e1-a07f-4dbd-be51-cb6629d619e2", + "metadata": {}, + "outputs": [ { - "cell_type": "markdown", - "id": "b42999f9-311f-481e-ae63-40a5577072c5", - "metadata": { - "id": "b42999f9-311f-481e-ae63-40a5577072c5" - }, - "source": [ - "## Bonus" - ] - }, + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "--- Análisis por Policy Type y Gender (Clientes con Respuesta 'Yes') ---\n", + " policy_type gender avg_monthly_premium_auto avg_clv avg_claim count\n", + "0 Corporate Auto F 94.30 7712.63 433.74 169\n", + "1 Corporate Auto M 92.19 7944.47 408.58 154\n", + "2 Personal Auto F 99.00 8339.79 452.97 540\n", + "3 Personal Auto M 91.09 7448.38 457.01 536\n", + "4 Special Auto F 92.31 7691.58 453.28 35\n", + "5 Special Auto M 86.34 8247.09 429.53 32\n", + "\n", + "**Conclusión sobre Rentabilidad/Riesgo:**\n", + "> Un segmento es potencialmente más 'rentable' si tiene un alto CLV/Prima promedio, pero un 'bajo' reclamo promedio (avg_claim).\n", + "> Busque segmentos con ALTO 'avg_clv' y BAJO 'avg_claim'.\n" + ] + } + ], + "source": [ + "# Análisis de clientes que respondieron \"Yes\"\n", + "\n", + "# Filtrar solo a los clientes con respuesta \"Yes\"\n", + "df_yes = df_clean[df_clean['response'] == 'Yes']\n", + "\n", + "# Agrupar por policy_type y gender, y calcular el promedio\n", + "df_analisis_yes = df_yes.groupby(['policy_type', 'gender']).agg(\n", + " avg_monthly_premium_auto=('monthly_premium_auto', 'mean'),\n", + " avg_clv=('customer_lifetime_value', 'mean'),\n", + " avg_claim=('total_claim_amount', 'mean'),\n", + " count=('customer', 'count') # Contamos el número de clientes en cada segmento\n", + ").reset_index()\n", + "\n", + "# Redondear las columnas numéricas para una mejor visualización\n", + "df_analisis_yes = df_analisis_yes.round(2)\n", + "\n", + "print(\"\\n--- Análisis por Policy Type y Gender (Clientes con Respuesta 'Yes') ---\")\n", + "print(df_analisis_yes)\n", + "print(\"\\n**Conclusión sobre Rentabilidad/Riesgo:**\")\n", + "print(\"> Un segmento es potencialmente más 'rentable' si tiene un alto CLV/Prima promedio, pero un 'bajo' reclamo promedio (avg_claim).\")\n", + "print(\"> Busque segmentos con ALTO 'avg_clv' y BAJO 'avg_claim'.\")" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "e3b6a07d-f4d4-4ad9-99e2-80542eb2f24c", + "metadata": {}, + "outputs": [ { - "cell_type": "markdown", - "id": "81ff02c5-6584-4f21-a358-b918697c6432", - "metadata": { - "id": "81ff02c5-6584-4f21-a358-b918697c6432" - }, - "source": [ - "5. The marketing team wants to analyze the number of policies sold by state and month. Present the data in a table where the months are arranged as columns and the states are arranged as rows." - ] - }, + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "--- Estados con más de 500 clientes ---\n", + " state total_customers\n", + "0 California 3552\n", + "1 Oregon 2909\n", + "2 Arizona 1937\n", + "3 Nevada 993\n", + "4 Washington 888\n" + ] + } + ], + "source": [ + "# Análisis de clientes por estado\n", + "\n", + "# Contar el número de clientes en cada estado\n", + "df_clientes_por_estado = df_clean['state'].value_counts().reset_index()\n", + "# asignar nombres claros a las columnas nuevas despues de .reset_index() modificando el dataframe que acabamos de crear df_clientes_por_estado\n", + "df_clientes_por_estado.columns = ['state', 'total_customers']\n", + "\n", + "# Definir el umbral de clientes\n", + "umbral_clientes = 500\n", + "# Filtrar los estados con más de 500 clientes\n", + "df_estados_populares = df_clientes_por_estado[df_clientes_por_estado['total_customers'] > umbral_clientes]\n", + "\n", + "print(f\"\\n--- Estados con más de {umbral_clientes} clientes ---\")\n", + "print(df_estados_populares)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "1e039461-f362-46d1-aa42-0180a91c0467", + "metadata": {}, + "outputs": [ { - "cell_type": "markdown", - "id": "b6aec097-c633-4017-a125-e77a97259cda", - "metadata": { - "id": "b6aec097-c633-4017-a125-e77a97259cda" - }, - "source": [ - "6. Display a new DataFrame that contains the number of policies sold by month, by state, for the top 3 states with the highest number of policies sold.\n", - "\n", - "*Hint:*\n", - "- *To accomplish this, you will first need to group the data by state and month, then count the number of policies sold for each group. Afterwards, you will need to sort the data by the count of policies sold in descending order.*\n", - "- *Next, you will select the top 3 states with the highest number of policies sold.*\n", - "- *Finally, you will create a new DataFrame that contains the number of policies sold by month for each of the top 3 states.*" - ] - }, + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "--- Estadísticas de Customer Lifetime Value (CLV) por Educación y Género ---\n", + " education gender max_clv min_clv median_clv\n", + "0 Bachelor F 73225.96 1904.00 5640.51\n", + "1 Bachelor M 67907.27 1898.01 5548.03\n", + "2 College F 61850.19 1898.68 5623.61\n", + "3 College M 61134.68 1918.12 6005.85\n", + "4 Doctor F 44856.11 2395.57 5332.46\n", + "5 Doctor M 32677.34 2267.60 5577.67\n", + "6 High School or Below F 55277.45 2144.92 6039.55\n", + "7 High School or Below M 83325.38 1940.98 6286.73\n", + "8 Master F 51016.07 2417.78 5729.86\n", + "9 Master M 50568.26 2272.31 5579.10\n", + "\n", + "**Conclusión sobre CLV:**\n", + "> La 'median_clv' ofrece una visión más robusta del CLV 'típico' para cada segmento que el promedio, ya que es menos sensible a los valores atípicos.\n", + "> Un segmento con una 'median_clv' alta podría ser un objetivo valioso para futuras campañas.\n" + ] + } + ], + "source": [ + "# Máximo, mínimo y mediana de CLV por Educación y Género\n", + "\n", + "df_clv_por_segmento = df_clean.groupby(['education', 'gender']).agg(\n", + " max_clv=('customer_lifetime_value', 'max'),\n", + " min_clv=('customer_lifetime_value', 'min'),\n", + " median_clv=('customer_lifetime_value', 'median')\n", + ").reset_index()\n", + "\n", + "# Redondear las columnas numéricas para una mejor visualización\n", + "df_clv_por_segmento = df_clv_por_segmento.round(2)\n", + "\n", + "print(\"\\n--- Estadísticas de Customer Lifetime Value (CLV) por Educación y Género ---\")\n", + "print(df_clv_por_segmento)\n", + "\n", + "print(\"\\n**Conclusión sobre CLV:**\")\n", + "print(\"> La 'median_clv' ofrece una visión más robusta del CLV 'típico' para cada segmento que el promedio, ya que es menos sensible a los valores atípicos.\")\n", + "print(\"> Un segmento con una 'median_clv' alta podría ser un objetivo valioso para futuras campañas.\")" + ] + }, + { + "cell_type": "markdown", + "id": "b42999f9-311f-481e-ae63-40a5577072c5", + "metadata": { + "id": "b42999f9-311f-481e-ae63-40a5577072c5" + }, + "source": [ + "## Bonus" + ] + }, + { + "cell_type": "markdown", + "id": "81ff02c5-6584-4f21-a358-b918697c6432", + "metadata": { + "id": "81ff02c5-6584-4f21-a358-b918697c6432" + }, + "source": [ + "5. The marketing team wants to analyze the number of policies sold by state and month. Present the data in a table where the months are arranged as columns and the states are arranged as rows." + ] + }, + { + "cell_type": "markdown", + "id": "b6aec097-c633-4017-a125-e77a97259cda", + "metadata": { + "id": "b6aec097-c633-4017-a125-e77a97259cda" + }, + "source": [ + "6. Display a new DataFrame that contains the number of policies sold by month, by state, for the top 3 states with the highest number of policies sold.\n", + "\n", + "*Hint:*\n", + "- *To accomplish this, you will first need to group the data by state and month, then count the number of policies sold for each group. Afterwards, you will need to sort the data by the count of policies sold in descending order.*\n", + "- *Next, you will select the top 3 states with the highest number of policies sold.*\n", + "- *Finally, you will create a new DataFrame that contains the number of policies sold by month for each of the top 3 states.*" + ] + }, + { + "cell_type": "markdown", + "id": "ba975b8a-a2cf-4fbf-9f59-ebc381767009", + "metadata": { + "id": "ba975b8a-a2cf-4fbf-9f59-ebc381767009" + }, + "source": [ + "7. The marketing team wants to analyze the effect of different marketing channels on the customer response rate.\n", + "\n", + "Hint: You can use melt to unpivot the data and create a table that shows the customer response rate (those who responded \"Yes\") by marketing channel." + ] + }, + { + "cell_type": "markdown", + "id": "e4378d94-48fb-4850-a802-b1bc8f427b2d", + "metadata": { + "id": "e4378d94-48fb-4850-a802-b1bc8f427b2d" + }, + "source": [ + "External Resources for Data Filtering: https://towardsdatascience.com/filtering-data-frames-in-pandas-b570b1f834b9" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "449513f4-0459-46a0-a18d-9398d974c9ad", + "metadata": { + "id": "449513f4-0459-46a0-a18d-9398d974c9ad" + }, + "outputs": [ { - "cell_type": "markdown", - "id": "ba975b8a-a2cf-4fbf-9f59-ebc381767009", - "metadata": { - "id": "ba975b8a-a2cf-4fbf-9f59-ebc381767009" - }, - "source": [ - "7. The marketing team wants to analyze the effect of different marketing channels on the customer response rate.\n", - "\n", - "Hint: You can use melt to unpivot the data and create a table that shows the customer response rate (those who responded \"Yes\") by marketing channel." - ] + "name": "stdout", + "output_type": "stream", + "text": [ + "--- 📚 Pólizas Vendidas por Estado y Mes (Tabla Pivotante Completa) ---\n", + "month January February March April May June July August \\\n", + "state \n", + "Arizona 1008 929 0 0 0 0 0 0 \n", + "California 1918 1634 0 0 0 0 0 0 \n", + "Nevada 551 442 0 0 0 0 0 0 \n", + "Oregon 1565 1344 0 0 0 0 0 0 \n", + "Washington 463 425 0 0 0 0 0 0 \n", + "\n", + "month September October November December \n", + "state \n", + "Arizona 0 0 0 0 \n", + "California 0 0 0 0 \n", + "Nevada 0 0 0 0 \n", + "Oregon 0 0 0 0 \n", + "Washington 0 0 0 0 \n" + ] }, { - "cell_type": "markdown", - "id": "e4378d94-48fb-4850-a802-b1bc8f427b2d", - "metadata": { - "id": "e4378d94-48fb-4850-a802-b1bc8f427b2d" - }, - "source": [ - "External Resources for Data Filtering: https://towardsdatascience.com/filtering-data-frames-in-pandas-b570b1f834b9" - ] - }, + "name": "stderr", + "output_type": "stream", + "text": [ + "C:\\Users\\Marta\\AppData\\Local\\Temp\\ipykernel_7440\\270360997.py:13: FutureWarning: The default value of observed=False is deprecated and will change to observed=True in a future version of pandas. Specify observed=False to silence this warning and retain the current behavior\n", + " df_policies_by_month_state = pd.pivot_table(\n" + ] + } + ], + "source": [ + "# Usamos 'effective_to_date' como sustituto de 'policy_issue_date'\n", + "df_clean['effective_to_date'] = pd.to_datetime(df_clean['effective_to_date'], errors='coerce')\n", + "\n", + "# Extraer el nombre del mes\n", + "df_clean['month'] = df_clean['effective_to_date'].dt.strftime('%B')\n", + "\n", + "# Definir el orden correcto de los meses (para pivotar correctamente)\n", + "month_order = ['January', 'February', 'March', 'April', 'May', 'June',\n", + " 'July', 'August', 'September', 'October', 'November', 'December']\n", + "df_clean['month'] = pd.Categorical(df_clean['month'], categories=month_order, ordered=True)\n", + "\n", + "# Crear la tabla pivotante (Continúa igual)\n", + "df_policies_by_month_state = pd.pivot_table(\n", + " df_clean,\n", + " index='state', \n", + " columns='month', \n", + " values='customer', \n", + " aggfunc='count' \n", + ").fillna(0)\n", + "print(\"--- 📚 Pólizas Vendidas por Estado y Mes (Tabla Pivotante Completa) ---\")\n", + "print(df_policies_by_month_state.head())" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "f32c252f-ac9a-4b70-96be-555414a54eee", + "metadata": {}, + "outputs": [ { - "cell_type": "code", - "execution_count": null, - "id": "449513f4-0459-46a0-a18d-9398d974c9ad", - "metadata": { - "id": "449513f4-0459-46a0-a18d-9398d974c9ad" - }, - "outputs": [], - "source": [ - "# your code goes here" - ] + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "--- Top 3 Estados con Mayor Número de Pólizas Vendidas ---\n", + "['California', 'Oregon', 'Arizona']\n" + ] } - ], - "metadata": { - "colab": { - "provenance": [] - }, - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.9.13" + ], + "source": [ + "# 1. Agrupar por estado y contar el total de pólizas\n", + "df_total_policies_by_state = df_clean.groupby('state')['customer'].count()\n", + "\n", + "# 2. Ordenar y seleccionar los 3 estados principales\n", + "top_3_states = df_total_policies_by_state.sort_values(ascending=False).head(3).index.tolist()\n", + "\n", + "print(f\"\\n--- Top 3 Estados con Mayor Número de Pólizas Vendidas ---\")\n", + "print(top_3_states)" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "e902e02e-2d8b-4523-8c2b-a559e5f60315", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "--- 🏆 Pólizas Vendidas por Mes para el Top 3 de Estados ---\n", + "month January February March April May June July August \\\n", + "state \n", + "California 1918 1634 0 0 0 0 0 0 \n", + "Oregon 1565 1344 0 0 0 0 0 0 \n", + "Arizona 1008 929 0 0 0 0 0 0 \n", + "\n", + "month September October November December \n", + "state \n", + "California 0 0 0 0 \n", + "Oregon 0 0 0 0 \n", + "Arizona 0 0 0 0 \n" + ] } + ], + "source": [ + "## DataFrame del Top 3 de Estados\n", + "\n", + "df_top_3_policies_by_month_state = df_policies_by_month_state.loc[top_3_states]\n", + "\n", + "print(\"\\n--- 🏆 Pólizas Vendidas por Mes para el Top 3 de Estados ---\")\n", + "print(df_top_3_policies_by_month_state)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cfe782c1-e5a4-4761-8ae4-e84be819eaca", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "colab": { + "provenance": [] + }, + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" }, - "nbformat": 4, - "nbformat_minor": 5 + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.13.9" + } + }, + "nbformat": 4, + "nbformat_minor": 5 }