diff --git a/.DS_Store b/.DS_Store
deleted file mode 100644
index 01222e6..0000000
Binary files a/.DS_Store and /dev/null differ
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..87620ac
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+.ipynb_checkpoints/
diff --git a/lab-dw-data-structuring-and-combining.ipynb b/lab-dw-data-structuring-and-combining.ipynb
index ec4e3f9..235315b 100644
--- a/lab-dw-data-structuring-and-combining.ipynb
+++ b/lab-dw-data-structuring-and-combining.ipynb
@@ -36,16 +36,984 @@
},
{
"cell_type": "code",
- "execution_count": null,
- "id": "492d06e3-92c7-4105-ac72-536db98d3244",
- "metadata": {
- "id": "492d06e3-92c7-4105-ac72-536db98d3244"
- },
- "outputs": [],
+ "execution_count": 1,
+ "id": "c56f21e2-c016-4f75-8324-150fe4ce18a5",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "File 1 shape: (4008, 11)\n",
+ "File 2 shape: (996, 11)\n",
+ "File 3 shape: (7070, 11)\n",
+ "\n",
+ "File 1 columns:\n",
+ "['customer', 'state', 'gender', 'education', 'customer_lifetime_value', 'income', 'monthly_premium_auto', 'number_of_open_complaints', 'policy_type', 'vehicle_class', 'total_claim_amount']\n",
+ "\n",
+ "File 2 columns:\n",
+ "['customer', 'state', 'gender', 'education', 'customer_lifetime_value', 'income', 'monthly_premium_auto', 'number_of_open_complaints', 'total_claim_amount', 'policy_type', 'vehicle_class']\n",
+ "\n",
+ "File 3 columns:\n",
+ "['customer', 'state', 'customer_lifetime_value', 'education', 'gender', 'income', 'monthly_premium_auto', 'number_of_open_complaints', 'policy_type', 'total_claim_amount', 'vehicle_class']\n",
+ "\n",
+ "Columns missing from File 1:\n",
+ "[]\n",
+ "\n",
+ "Columns missing from File 2:\n",
+ "[]\n",
+ "\n",
+ "Columns missing from File 3:\n",
+ "[]\n",
+ "\n",
+ "Combined dataset shape before cleaning: (12074, 11)\n",
+ "\n",
+ "Missing values before cleaning:\n"
+ ]
+ },
+ {
+ "data": {
+ "text/html": [
+ "
\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " missing_values | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | gender | \n",
+ " 3059 | \n",
+ "
\n",
+ " \n",
+ " | customer_lifetime_value | \n",
+ " 2944 | \n",
+ "
\n",
+ " \n",
+ " | customer | \n",
+ " 2937 | \n",
+ "
\n",
+ " \n",
+ " | state | \n",
+ " 2937 | \n",
+ "
\n",
+ " \n",
+ " | education | \n",
+ " 2937 | \n",
+ "
\n",
+ " \n",
+ " | income | \n",
+ " 2937 | \n",
+ "
\n",
+ " \n",
+ " | monthly_premium_auto | \n",
+ " 2937 | \n",
+ "
\n",
+ " \n",
+ " | number_of_open_complaints | \n",
+ " 2937 | \n",
+ "
\n",
+ " \n",
+ " | policy_type | \n",
+ " 2937 | \n",
+ "
\n",
+ " \n",
+ " | vehicle_class | \n",
+ " 2937 | \n",
+ "
\n",
+ " \n",
+ " | total_claim_amount | \n",
+ " 2937 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " missing_values\n",
+ "gender 3059\n",
+ "customer_lifetime_value 2944\n",
+ "customer 2937\n",
+ "state 2937\n",
+ "education 2937\n",
+ "income 2937\n",
+ "monthly_premium_auto 2937\n",
+ "number_of_open_complaints 2937\n",
+ "policy_type 2937\n",
+ "vehicle_class 2937\n",
+ "total_claim_amount 2937"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "\n",
+ "Missing values after cleaning:\n"
+ ]
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " missing_values | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | customer | \n",
+ " 0 | \n",
+ "
\n",
+ " \n",
+ " | state | \n",
+ " 0 | \n",
+ "
\n",
+ " \n",
+ " | gender | \n",
+ " 0 | \n",
+ "
\n",
+ " \n",
+ " | education | \n",
+ " 0 | \n",
+ "
\n",
+ " \n",
+ " | customer_lifetime_value | \n",
+ " 0 | \n",
+ "
\n",
+ " \n",
+ " | income | \n",
+ " 0 | \n",
+ "
\n",
+ " \n",
+ " | monthly_premium_auto | \n",
+ " 0 | \n",
+ "
\n",
+ " \n",
+ " | number_of_open_complaints | \n",
+ " 0 | \n",
+ "
\n",
+ " \n",
+ " | policy_type | \n",
+ " 0 | \n",
+ "
\n",
+ " \n",
+ " | vehicle_class | \n",
+ " 0 | \n",
+ "
\n",
+ " \n",
+ " | total_claim_amount | \n",
+ " 0 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " missing_values\n",
+ "customer 0\n",
+ "state 0\n",
+ "gender 0\n",
+ "education 0\n",
+ "customer_lifetime_value 0\n",
+ "income 0\n",
+ "monthly_premium_auto 0\n",
+ "number_of_open_complaints 0\n",
+ "policy_type 0\n",
+ "vehicle_class 0\n",
+ "total_claim_amount 0"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "\n",
+ "Cleaning results:\n",
+ "Final shape: (9134, 11)\n",
+ "Duplicates removed: 3\n",
+ "Remaining duplicates: 0\n",
+ "Remaining missing values: 0\n",
+ "\n",
+ "Final columns:\n",
+ "['customer', 'state', 'gender', 'education', 'customer_lifetime_value', 'income', 'monthly_premium_auto', 'number_of_open_complaints', 'policy_type', 'vehicle_class', 'total_claim_amount']\n",
+ "\n",
+ "Final data types:\n"
+ ]
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " data_type | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | customer | \n",
+ " string | \n",
+ "
\n",
+ " \n",
+ " | state | \n",
+ " string | \n",
+ "
\n",
+ " \n",
+ " | gender | \n",
+ " string | \n",
+ "
\n",
+ " \n",
+ " | education | \n",
+ " string | \n",
+ "
\n",
+ " \n",
+ " | customer_lifetime_value | \n",
+ " Float64 | \n",
+ "
\n",
+ " \n",
+ " | income | \n",
+ " int64 | \n",
+ "
\n",
+ " \n",
+ " | monthly_premium_auto | \n",
+ " float64 | \n",
+ "
\n",
+ " \n",
+ " | number_of_open_complaints | \n",
+ " int64 | \n",
+ "
\n",
+ " \n",
+ " | policy_type | \n",
+ " string | \n",
+ "
\n",
+ " \n",
+ " | vehicle_class | \n",
+ " string | \n",
+ "
\n",
+ " \n",
+ " | total_claim_amount | \n",
+ " float64 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " data_type\n",
+ "customer string\n",
+ "state string\n",
+ "gender string\n",
+ "education string\n",
+ "customer_lifetime_value Float64\n",
+ "income int64\n",
+ "monthly_premium_auto float64\n",
+ "number_of_open_complaints int64\n",
+ "policy_type string\n",
+ "vehicle_class string\n",
+ "total_claim_amount float64"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "\n",
+ "First 10 cleaned rows:\n"
+ ]
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " customer | \n",
+ " state | \n",
+ " gender | \n",
+ " education | \n",
+ " customer_lifetime_value | \n",
+ " income | \n",
+ " monthly_premium_auto | \n",
+ " number_of_open_complaints | \n",
+ " policy_type | \n",
+ " vehicle_class | \n",
+ " total_claim_amount | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " RB50392 | \n",
+ " Washington | \n",
+ " Female | \n",
+ " Master | \n",
+ " 7714.88 | \n",
+ " 0 | \n",
+ " 1000.0 | \n",
+ " 0 | \n",
+ " Personal Auto | \n",
+ " Four-Door Car | \n",
+ " 2.70 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " QZ44356 | \n",
+ " Arizona | \n",
+ " Female | \n",
+ " Bachelor | \n",
+ " 697953.59 | \n",
+ " 0 | \n",
+ " 94.0 | \n",
+ " 0 | \n",
+ " Personal Auto | \n",
+ " Four-Door Car | \n",
+ " 1131.46 | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " AI49188 | \n",
+ " Nevada | \n",
+ " Female | \n",
+ " Bachelor | \n",
+ " 1288743.17 | \n",
+ " 48767 | \n",
+ " 108.0 | \n",
+ " 0 | \n",
+ " Personal Auto | \n",
+ " Two-Door Car | \n",
+ " 566.47 | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " WW63253 | \n",
+ " California | \n",
+ " Male | \n",
+ " Bachelor | \n",
+ " 764586.18 | \n",
+ " 0 | \n",
+ " 106.0 | \n",
+ " 0 | \n",
+ " Corporate Auto | \n",
+ " SUV | \n",
+ " 529.88 | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " GA49547 | \n",
+ " Washington | \n",
+ " Male | \n",
+ " High School or Below | \n",
+ " 536307.65 | \n",
+ " 36357 | \n",
+ " 68.0 | \n",
+ " 0 | \n",
+ " Personal Auto | \n",
+ " Four-Door Car | \n",
+ " 17.27 | \n",
+ "
\n",
+ " \n",
+ " | 5 | \n",
+ " OC83172 | \n",
+ " Oregon | \n",
+ " Female | \n",
+ " Bachelor | \n",
+ " 825629.78 | \n",
+ " 62902 | \n",
+ " 69.0 | \n",
+ " 0 | \n",
+ " Personal Auto | \n",
+ " Two-Door Car | \n",
+ " 159.38 | \n",
+ "
\n",
+ " \n",
+ " | 6 | \n",
+ " XZ87318 | \n",
+ " Oregon | \n",
+ " Female | \n",
+ " College | \n",
+ " 538089.86 | \n",
+ " 55350 | \n",
+ " 67.0 | \n",
+ " 0 | \n",
+ " Corporate Auto | \n",
+ " Four-Door Car | \n",
+ " 321.60 | \n",
+ "
\n",
+ " \n",
+ " | 7 | \n",
+ " CF85061 | \n",
+ " Arizona | \n",
+ " Male | \n",
+ " Master | \n",
+ " 721610.03 | \n",
+ " 0 | \n",
+ " 101.0 | \n",
+ " 0 | \n",
+ " Corporate Auto | \n",
+ " Four-Door Car | \n",
+ " 363.03 | \n",
+ "
\n",
+ " \n",
+ " | 8 | \n",
+ " DY87989 | \n",
+ " Oregon | \n",
+ " Male | \n",
+ " Bachelor | \n",
+ " 2412750.4 | \n",
+ " 14072 | \n",
+ " 71.0 | \n",
+ " 0 | \n",
+ " Corporate Auto | \n",
+ " Four-Door Car | \n",
+ " 511.20 | \n",
+ "
\n",
+ " \n",
+ " | 9 | \n",
+ " BQ94931 | \n",
+ " Oregon | \n",
+ " Female | \n",
+ " College | \n",
+ " 738817.81 | \n",
+ " 28812 | \n",
+ " 93.0 | \n",
+ " 0 | \n",
+ " Special Auto | \n",
+ " Four-Door Car | \n",
+ " 425.53 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " customer state gender education customer_lifetime_value \\\n",
+ "0 RB50392 Washington Female Master 7714.88 \n",
+ "1 QZ44356 Arizona Female Bachelor 697953.59 \n",
+ "2 AI49188 Nevada Female Bachelor 1288743.17 \n",
+ "3 WW63253 California Male Bachelor 764586.18 \n",
+ "4 GA49547 Washington Male High School or Below 536307.65 \n",
+ "5 OC83172 Oregon Female Bachelor 825629.78 \n",
+ "6 XZ87318 Oregon Female College 538089.86 \n",
+ "7 CF85061 Arizona Male Master 721610.03 \n",
+ "8 DY87989 Oregon Male Bachelor 2412750.4 \n",
+ "9 BQ94931 Oregon Female College 738817.81 \n",
+ "\n",
+ " income monthly_premium_auto number_of_open_complaints policy_type \\\n",
+ "0 0 1000.0 0 Personal Auto \n",
+ "1 0 94.0 0 Personal Auto \n",
+ "2 48767 108.0 0 Personal Auto \n",
+ "3 0 106.0 0 Corporate Auto \n",
+ "4 36357 68.0 0 Personal Auto \n",
+ "5 62902 69.0 0 Personal Auto \n",
+ "6 55350 67.0 0 Corporate Auto \n",
+ "7 0 101.0 0 Corporate Auto \n",
+ "8 14072 71.0 0 Corporate Auto \n",
+ "9 28812 93.0 0 Special Auto \n",
+ "\n",
+ " vehicle_class total_claim_amount \n",
+ "0 Four-Door Car 2.70 \n",
+ "1 Four-Door Car 1131.46 \n",
+ "2 Two-Door Car 566.47 \n",
+ "3 SUV 529.88 \n",
+ "4 Four-Door Car 17.27 \n",
+ "5 Two-Door Car 159.38 \n",
+ "6 Four-Door Car 321.60 \n",
+ "7 Four-Door Car 363.03 \n",
+ "8 Four-Door Car 511.20 \n",
+ "9 Four-Door Car 425.53 "
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "\n",
+ "Numerical summary:\n"
+ ]
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " customer_lifetime_value | \n",
+ " income | \n",
+ " monthly_premium_auto | \n",
+ " number_of_open_complaints | \n",
+ " total_claim_amount | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | count | \n",
+ " 9134.0 | \n",
+ " 9134.00 | \n",
+ " 9134.00 | \n",
+ " 9134.00 | \n",
+ " 9134.00 | \n",
+ "
\n",
+ " \n",
+ " | mean | \n",
+ " 181937.9 | \n",
+ " 37824.85 | \n",
+ " 110.39 | \n",
+ " 0.38 | \n",
+ " 430.48 | \n",
+ "
\n",
+ " \n",
+ " | std | \n",
+ " 440903.85 | \n",
+ " 30359.23 | \n",
+ " 581.47 | \n",
+ " 0.91 | \n",
+ " 289.62 | \n",
+ "
\n",
+ " \n",
+ " | min | \n",
+ " 1898.01 | \n",
+ " 0.00 | \n",
+ " 61.00 | \n",
+ " 0.00 | \n",
+ " 0.10 | \n",
+ "
\n",
+ " \n",
+ " | 25% | \n",
+ " 4650.06 | \n",
+ " 0.00 | \n",
+ " 68.00 | \n",
+ " 0.00 | \n",
+ " 266.96 | \n",
+ "
\n",
+ " \n",
+ " | 50% | \n",
+ " 7714.88 | \n",
+ " 34240.00 | \n",
+ " 83.00 | \n",
+ " 0.00 | \n",
+ " 377.50 | \n",
+ "
\n",
+ " \n",
+ " | 75% | \n",
+ " 26131.72 | \n",
+ " 62446.50 | \n",
+ " 109.00 | \n",
+ " 0.00 | \n",
+ " 546.05 | \n",
+ "
\n",
+ " \n",
+ " | max | \n",
+ " 5816655.35 | \n",
+ " 99981.00 | \n",
+ " 35354.00 | \n",
+ " 5.00 | \n",
+ " 2893.24 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " customer_lifetime_value income monthly_premium_auto \\\n",
+ "count 9134.0 9134.00 9134.00 \n",
+ "mean 181937.9 37824.85 110.39 \n",
+ "std 440903.85 30359.23 581.47 \n",
+ "min 1898.01 0.00 61.00 \n",
+ "25% 4650.06 0.00 68.00 \n",
+ "50% 7714.88 34240.00 83.00 \n",
+ "75% 26131.72 62446.50 109.00 \n",
+ "max 5816655.35 99981.00 35354.00 \n",
+ "\n",
+ " number_of_open_complaints total_claim_amount \n",
+ "count 9134.00 9134.00 \n",
+ "mean 0.38 430.48 \n",
+ "std 0.91 289.62 \n",
+ "min 0.00 0.10 \n",
+ "25% 0.00 266.96 \n",
+ "50% 0.00 377.50 \n",
+ "75% 0.00 546.05 \n",
+ "max 5.00 2893.24 "
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "\n",
+ "Categorical summary:\n"
+ ]
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " customer | \n",
+ " state | \n",
+ " gender | \n",
+ " education | \n",
+ " policy_type | \n",
+ " vehicle_class | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | count | \n",
+ " 9134 | \n",
+ " 9134 | \n",
+ " 9134 | \n",
+ " 9134 | \n",
+ " 9134 | \n",
+ " 9134 | \n",
+ "
\n",
+ " \n",
+ " | unique | \n",
+ " 9056 | \n",
+ " 5 | \n",
+ " 2 | \n",
+ " 5 | \n",
+ " 3 | \n",
+ " 4 | \n",
+ "
\n",
+ " \n",
+ " | top | \n",
+ " GA49547 | \n",
+ " California | \n",
+ " Female | \n",
+ " Bachelor | \n",
+ " Personal Auto | \n",
+ " Four-Door Car | \n",
+ "
\n",
+ " \n",
+ " | freq | \n",
+ " 2 | \n",
+ " 3150 | \n",
+ " 4726 | \n",
+ " 2742 | \n",
+ " 6790 | \n",
+ " 4640 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " customer state gender education policy_type vehicle_class\n",
+ "count 9134 9134 9134 9134 9134 9134\n",
+ "unique 9056 5 2 5 3 4\n",
+ "top GA49547 California Female Bachelor Personal Auto Four-Door Car\n",
+ "freq 2 3150 4726 2742 6790 4640"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "\n",
+ "Cleaned dataset saved as cleaned_customer_data.csv\n"
+ ]
+ }
+ ],
"source": [
- "# Your code goes here"
+ "import pandas as pd\n",
+ "import numpy as np\n",
+ "from IPython.display import display\n",
+ "\n",
+ "url1 = \"https://raw.githubusercontent.com/data-bootcamp-v4/data/main/file1.csv\"\n",
+ "url2 = \"https://raw.githubusercontent.com/data-bootcamp-v4/data/main/file2.csv\"\n",
+ "url3 = \"https://raw.githubusercontent.com/data-bootcamp-v4/data/main/file3.csv\"\n",
+ "\n",
+ "df1 = pd.read_csv(url1)\n",
+ "df2 = pd.read_csv(url2)\n",
+ "df3 = pd.read_csv(url3)\n",
+ "\n",
+ "def standardize_columns(dataframe):\n",
+ " dataframe = dataframe.copy()\n",
+ " dataframe.columns = dataframe.columns.str.strip().str.lower().str.replace(\" \", \"_\", regex=False)\n",
+ " dataframe = dataframe.rename(columns={\"st\": \"state\"})\n",
+ " return dataframe\n",
+ "\n",
+ "df1 = standardize_columns(df1)\n",
+ "df2 = standardize_columns(df2)\n",
+ "df3 = standardize_columns(df3)\n",
+ "\n",
+ "print(\"File 1 shape:\", df1.shape)\n",
+ "print(\"File 2 shape:\", df2.shape)\n",
+ "print(\"File 3 shape:\", df3.shape)\n",
+ "\n",
+ "print(\"\\nFile 1 columns:\")\n",
+ "print(df1.columns.tolist())\n",
+ "\n",
+ "print(\"\\nFile 2 columns:\")\n",
+ "print(df2.columns.tolist())\n",
+ "\n",
+ "print(\"\\nFile 3 columns:\")\n",
+ "print(df3.columns.tolist())\n",
+ "\n",
+ "all_columns = sorted(set(df1.columns) | set(df2.columns) | set(df3.columns))\n",
+ "\n",
+ "print(\"\\nColumns missing from File 1:\")\n",
+ "print(sorted(set(all_columns) - set(df1.columns)))\n",
+ "\n",
+ "print(\"\\nColumns missing from File 2:\")\n",
+ "print(sorted(set(all_columns) - set(df2.columns)))\n",
+ "\n",
+ "print(\"\\nColumns missing from File 3:\")\n",
+ "print(sorted(set(all_columns) - set(df3.columns)))\n",
+ "\n",
+ "df = pd.concat([df1, df2, df3], ignore_index=True, sort=False)\n",
+ "\n",
+ "print(\"\\nCombined dataset shape before cleaning:\", df.shape)\n",
+ "\n",
+ "print(\"\\nMissing values before cleaning:\")\n",
+ "display(df.isnull().sum().sort_values(ascending=False).to_frame(\"missing_values\"))\n",
+ "\n",
+ "df = df.dropna(how=\"all\").reset_index(drop=True)\n",
+ "\n",
+ "text_columns = df.select_dtypes(include=[\"object\", \"string\"]).columns\n",
+ "\n",
+ "for column in text_columns:\n",
+ " df[column] = df[column].astype(\"string\").str.strip()\n",
+ "\n",
+ "if \"gender\" in df.columns:\n",
+ " df[\"gender\"] = df[\"gender\"].str.lower().replace({\n",
+ " \"m\": \"Male\",\n",
+ " \"male\": \"Male\",\n",
+ " \"f\": \"Female\",\n",
+ " \"female\": \"Female\",\n",
+ " \"femal\": \"Female\"\n",
+ " })\n",
+ "\n",
+ "if \"state\" in df.columns:\n",
+ " df[\"state\"] = df[\"state\"].replace({\n",
+ " \"AZ\": \"Arizona\",\n",
+ " \"Cali\": \"California\",\n",
+ " \"WA\": \"Washington\"\n",
+ " })\n",
+ "\n",
+ "if \"education\" in df.columns:\n",
+ " df[\"education\"] = df[\"education\"].replace({\n",
+ " \"Bachelors\": \"Bachelor\"\n",
+ " })\n",
+ "\n",
+ "if \"vehicle_class\" in df.columns:\n",
+ " df[\"vehicle_class\"] = df[\"vehicle_class\"].replace({\n",
+ " \"Sports Car\": \"Luxury\",\n",
+ " \"Luxury SUV\": \"Luxury\",\n",
+ " \"Luxury Car\": \"Luxury\"\n",
+ " })\n",
+ "\n",
+ "if \"customer_lifetime_value\" in df.columns:\n",
+ " df[\"customer_lifetime_value\"] = pd.to_numeric(\n",
+ " df[\"customer_lifetime_value\"].astype(\"string\").str.replace(\"%\", \"\", regex=False).str.replace(\",\", \"\", regex=False),\n",
+ " errors=\"coerce\"\n",
+ " )\n",
+ "\n",
+ "def clean_complaints(value):\n",
+ " if pd.isna(value):\n",
+ " return np.nan\n",
+ "\n",
+ " value = str(value).strip()\n",
+ "\n",
+ " if \"/\" in value:\n",
+ " parts = value.split(\"/\")\n",
+ " if len(parts) > 1:\n",
+ " return pd.to_numeric(parts[1], errors=\"coerce\")\n",
+ "\n",
+ " return pd.to_numeric(value, errors=\"coerce\")\n",
+ "\n",
+ "if \"number_of_open_complaints\" in df.columns:\n",
+ " df[\"number_of_open_complaints\"] = df[\"number_of_open_complaints\"].apply(clean_complaints)\n",
+ "\n",
+ "numeric_columns = [\"income\", \"monthly_premium_auto\", \"total_claim_amount\"]\n",
+ "\n",
+ "for column in numeric_columns:\n",
+ " if column in df.columns:\n",
+ " df[column] = pd.to_numeric(df[column], errors=\"coerce\")\n",
+ "\n",
+ "categorical_columns = df.select_dtypes(include=[\"object\", \"string\"]).columns\n",
+ "\n",
+ "for column in categorical_columns:\n",
+ " mode_value = df[column].mode(dropna=True)\n",
+ " if not mode_value.empty:\n",
+ " df[column] = df[column].fillna(mode_value.iloc[0])\n",
+ "\n",
+ "numeric_columns_to_fill = [\n",
+ " \"customer_lifetime_value\",\n",
+ " \"income\",\n",
+ " \"monthly_premium_auto\",\n",
+ " \"number_of_open_complaints\",\n",
+ " \"total_claim_amount\"\n",
+ "]\n",
+ "\n",
+ "for column in numeric_columns_to_fill:\n",
+ " if column in df.columns:\n",
+ " df[column] = df[column].fillna(df[column].median())\n",
+ "\n",
+ "duplicates_before = df.duplicated().sum()\n",
+ "\n",
+ "df = df.drop_duplicates().reset_index(drop=True)\n",
+ "\n",
+ "decimal_columns = [\"customer_lifetime_value\", \"monthly_premium_auto\", \"total_claim_amount\"]\n",
+ "\n",
+ "for column in decimal_columns:\n",
+ " if column in df.columns:\n",
+ " df[column] = df[column].round(2)\n",
+ "\n",
+ "if \"income\" in df.columns:\n",
+ " df[\"income\"] = df[\"income\"].round().astype(int)\n",
+ "\n",
+ "if \"number_of_open_complaints\" in df.columns:\n",
+ " df[\"number_of_open_complaints\"] = df[\"number_of_open_complaints\"].round().astype(int)\n",
+ "\n",
+ "print(\"\\nMissing values after cleaning:\")\n",
+ "display(df.isnull().sum().sort_values(ascending=False).to_frame(\"missing_values\"))\n",
+ "\n",
+ "print(\"\\nCleaning results:\")\n",
+ "print(\"Final shape:\", df.shape)\n",
+ "print(\"Duplicates removed:\", duplicates_before)\n",
+ "print(\"Remaining duplicates:\", df.duplicated().sum())\n",
+ "print(\"Remaining missing values:\", df.isnull().sum().sum())\n",
+ "\n",
+ "print(\"\\nFinal columns:\")\n",
+ "print(df.columns.tolist())\n",
+ "\n",
+ "print(\"\\nFinal data types:\")\n",
+ "display(df.dtypes.to_frame(\"data_type\"))\n",
+ "\n",
+ "print(\"\\nFirst 10 cleaned rows:\")\n",
+ "display(df.head(10))\n",
+ "\n",
+ "print(\"\\nNumerical summary:\")\n",
+ "display(df.describe().round(2))\n",
+ "\n",
+ "print(\"\\nCategorical summary:\")\n",
+ "display(df.describe(include=[\"object\", \"string\"]))\n",
+ "\n",
+ "df.to_csv(\"cleaned_customer_data.csv\", index=False)\n",
+ "\n",
+ "print(\"\\nCleaned dataset saved as cleaned_customer_data.csv\")"
]
},
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "33075a50-53a1-46ff-ba48-dd656d91fad1",
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ },
{
"cell_type": "markdown",
"id": "31b8a9e7-7db9-4604-991b-ef6771603e57",
@@ -72,14 +1040,571 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 2,
"id": "aa10d9b0-1c27-4d3f-a8e4-db6ab73bfd26",
"metadata": {
"id": "aa10d9b0-1c27-4d3f-a8e4-db6ab73bfd26"
},
- "outputs": [],
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Dataset shape: (10910, 27)\n"
+ ]
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " unnamed:_0 | \n",
+ " customer | \n",
+ " state | \n",
+ " customer_lifetime_value | \n",
+ " response | \n",
+ " coverage | \n",
+ " education | \n",
+ " effective_to_date | \n",
+ " employmentstatus | \n",
+ " gender | \n",
+ " ... | \n",
+ " number_of_policies | \n",
+ " policy_type | \n",
+ " policy | \n",
+ " renew_offer_type | \n",
+ " sales_channel | \n",
+ " total_claim_amount | \n",
+ " vehicle_class | \n",
+ " vehicle_size | \n",
+ " vehicle_type | \n",
+ " month | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " 0 | \n",
+ " DK49336 | \n",
+ " Arizona | \n",
+ " 4809.216960 | \n",
+ " No | \n",
+ " Basic | \n",
+ " College | \n",
+ " 2011-02-18 | \n",
+ " Employed | \n",
+ " M | \n",
+ " ... | \n",
+ " 9 | \n",
+ " Corporate Auto | \n",
+ " Corporate L3 | \n",
+ " Offer3 | \n",
+ " Agent | \n",
+ " 292.800000 | \n",
+ " Four-Door Car | \n",
+ " Medsize | \n",
+ " A | \n",
+ " 2 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " 1 | \n",
+ " KX64629 | \n",
+ " California | \n",
+ " 2228.525238 | \n",
+ " No | \n",
+ " Basic | \n",
+ " College | \n",
+ " 2011-01-18 | \n",
+ " Unemployed | \n",
+ " F | \n",
+ " ... | \n",
+ " 1 | \n",
+ " Personal Auto | \n",
+ " Personal L3 | \n",
+ " Offer4 | \n",
+ " Call Center | \n",
+ " 744.924331 | \n",
+ " Four-Door Car | \n",
+ " Medsize | \n",
+ " A | \n",
+ " 1 | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " 2 | \n",
+ " LZ68649 | \n",
+ " Washington | \n",
+ " 14947.917300 | \n",
+ " No | \n",
+ " Basic | \n",
+ " Bachelor | \n",
+ " 2011-02-10 | \n",
+ " Employed | \n",
+ " M | \n",
+ " ... | \n",
+ " 2 | \n",
+ " Personal Auto | \n",
+ " Personal L3 | \n",
+ " Offer3 | \n",
+ " Call Center | \n",
+ " 480.000000 | \n",
+ " SUV | \n",
+ " Medsize | \n",
+ " A | \n",
+ " 2 | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " 3 | \n",
+ " XL78013 | \n",
+ " Oregon | \n",
+ " 22332.439460 | \n",
+ " Yes | \n",
+ " Extended | \n",
+ " College | \n",
+ " 2011-01-11 | \n",
+ " Employed | \n",
+ " M | \n",
+ " ... | \n",
+ " 2 | \n",
+ " Corporate Auto | \n",
+ " Corporate L3 | \n",
+ " Offer2 | \n",
+ " Branch | \n",
+ " 484.013411 | \n",
+ " Four-Door Car | \n",
+ " Medsize | \n",
+ " A | \n",
+ " 1 | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " 4 | \n",
+ " QA50777 | \n",
+ " Oregon | \n",
+ " 9025.067525 | \n",
+ " No | \n",
+ " Premium | \n",
+ " Bachelor | \n",
+ " 2011-01-17 | \n",
+ " Medical Leave | \n",
+ " F | \n",
+ " ... | \n",
+ " 7 | \n",
+ " Personal Auto | \n",
+ " Personal L2 | \n",
+ " Offer1 | \n",
+ " Branch | \n",
+ " 707.925645 | \n",
+ " Four-Door Car | \n",
+ " Medsize | \n",
+ " A | \n",
+ " 1 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
5 rows × 27 columns
\n",
+ "
"
+ ],
+ "text/plain": [
+ " 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 2011-02-18 Employed M ... \n",
+ "1 Basic College 2011-01-18 Unemployed F ... \n",
+ "2 Basic Bachelor 2011-02-10 Employed M ... \n",
+ "3 Extended College 2011-01-11 Employed M ... \n",
+ "4 Premium Bachelor 2011-01-17 Medical Leave F ... \n",
+ "\n",
+ " number_of_policies policy_type policy renew_offer_type \\\n",
+ "0 9 Corporate Auto Corporate L3 Offer3 \n",
+ "1 1 Personal Auto Personal L3 Offer4 \n",
+ "2 2 Personal Auto Personal L3 Offer3 \n",
+ "3 2 Corporate Auto Corporate L3 Offer2 \n",
+ "4 7 Personal Auto Personal L2 Offer1 \n",
+ "\n",
+ " sales_channel total_claim_amount vehicle_class vehicle_size \\\n",
+ "0 Agent 292.800000 Four-Door Car Medsize \n",
+ "1 Call Center 744.924331 Four-Door Car Medsize \n",
+ "2 Call Center 480.000000 SUV Medsize \n",
+ "3 Branch 484.013411 Four-Door Car Medsize \n",
+ "4 Branch 707.925645 Four-Door Car Medsize \n",
+ "\n",
+ " vehicle_type month \n",
+ "0 A 2 \n",
+ "1 A 1 \n",
+ "2 A 2 \n",
+ "3 A 1 \n",
+ "4 A 1 \n",
+ "\n",
+ "[5 rows x 27 columns]"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "import pandas as pd\n",
+ "from IPython.display import display\n",
+ "\n",
+ "url = \"https://raw.githubusercontent.com/data-bootcamp-v4/data/main/marketing_customer_analysis_clean.csv\"\n",
+ "\n",
+ "df = pd.read_csv(url)\n",
+ "\n",
+ "print(\"Dataset shape:\", df.shape)\n",
+ "\n",
+ "display(\n",
+ " df.head()\n",
+ ")\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "48cc4648-de99-424f-ba53-db9c346ad834",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " sales_channel | \n",
+ " total_revenue | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " Agent | \n",
+ " 1810226.82 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " Branch | \n",
+ " 1301204.00 | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " Call Center | \n",
+ " 926600.82 | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " Web | \n",
+ " 706600.04 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " sales_channel total_revenue\n",
+ "0 Agent 1810226.82\n",
+ "1 Branch 1301204.00\n",
+ "2 Call Center 926600.82\n",
+ "3 Web 706600.04"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "The sales channel with the highest total revenue is Agent with 1,810,226.82.\n",
+ "The sales channel with the lowest total revenue is Web with 706,600.04.\n",
+ "The revenue difference between the highest and lowest sales channels is 1,103,626.78.\n"
+ ]
+ }
+ ],
+ "source": [
+ "sales_channel_revenue = (\n",
+ " pd.pivot_table(\n",
+ " df,\n",
+ " index=\"sales_channel\",\n",
+ " values=\"total_claim_amount\",\n",
+ " aggfunc=\"sum\"\n",
+ " )\n",
+ " .rename(\n",
+ " columns={\n",
+ " \"total_claim_amount\": \"total_revenue\"\n",
+ " }\n",
+ " )\n",
+ " .sort_values(\n",
+ " \"total_revenue\",\n",
+ " ascending=False\n",
+ " )\n",
+ " .round(2)\n",
+ " .reset_index()\n",
+ ")\n",
+ "\n",
+ "display(\n",
+ " sales_channel_revenue\n",
+ ")\n",
+ "\n",
+ "top_channel = sales_channel_revenue.iloc[0]\n",
+ "\n",
+ "lowest_channel = sales_channel_revenue.iloc[-1]\n",
+ "\n",
+ "difference = (\n",
+ " top_channel[\"total_revenue\"]\n",
+ " - lowest_channel[\"total_revenue\"]\n",
+ ")\n",
+ "\n",
+ "print(\n",
+ " f\"The sales channel with the highest total revenue is \"\n",
+ " f\"{top_channel['sales_channel']} with \"\n",
+ " f\"{top_channel['total_revenue']:,.2f}.\"\n",
+ ")\n",
+ "\n",
+ "print(\n",
+ " f\"The sales channel with the lowest total revenue is \"\n",
+ " f\"{lowest_channel['sales_channel']} with \"\n",
+ " f\"{lowest_channel['total_revenue']:,.2f}.\"\n",
+ ")\n",
+ "\n",
+ "print(\n",
+ " f\"The revenue difference between the highest and lowest \"\n",
+ " f\"sales channels is {difference:,.2f}.\"\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "8a4ddcf2-6001-49a2-b677-207c8f7e624c",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | gender | \n",
+ " F | \n",
+ " M | \n",
+ "
\n",
+ " \n",
+ " | education | \n",
+ " | \n",
+ " | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | Bachelor | \n",
+ " 7874.27 | \n",
+ " 7703.60 | \n",
+ "
\n",
+ " \n",
+ " | College | \n",
+ " 7748.82 | \n",
+ " 8052.46 | \n",
+ "
\n",
+ " \n",
+ " | Doctor | \n",
+ " 7328.51 | \n",
+ " 7415.33 | \n",
+ "
\n",
+ " \n",
+ " | High School or Below | \n",
+ " 8675.22 | \n",
+ " 8149.69 | \n",
+ "
\n",
+ " \n",
+ " | Master | \n",
+ " 8157.05 | \n",
+ " 8168.83 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ "gender F M\n",
+ "education \n",
+ "Bachelor 7874.27 7703.60\n",
+ "College 7748.82 8052.46\n",
+ "Doctor 7328.51 7415.33\n",
+ "High School or Below 8675.22 8149.69\n",
+ "Master 8157.05 8168.83"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "The segment with the highest average customer lifetime value is F customers with High School or Below education at 8,675.22.\n",
+ "The segment with the lowest average customer lifetime value is F customers with Doctor education at 7,328.51.\n",
+ "\n",
+ "Overall average customer lifetime value by gender\n"
+ ]
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " average_customer_lifetime_value | \n",
+ "
\n",
+ " \n",
+ " | gender | \n",
+ " | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | F | \n",
+ " 8071.11 | \n",
+ "
\n",
+ " \n",
+ " | M | \n",
+ " 7963.04 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " average_customer_lifetime_value\n",
+ "gender \n",
+ "F 8071.11\n",
+ "M 7963.04"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
"source": [
- "# Your code goes here"
+ "avg_clv_by_education_gender = pd.pivot_table(\n",
+ " df,\n",
+ " index=\"education\",\n",
+ " columns=\"gender\",\n",
+ " values=\"customer_lifetime_value\",\n",
+ " aggfunc=\"mean\"\n",
+ ").round(2)\n",
+ "\n",
+ "display(\n",
+ " avg_clv_by_education_gender\n",
+ ")\n",
+ "\n",
+ "clv_segments = (\n",
+ " avg_clv_by_education_gender\n",
+ " .stack()\n",
+ " .sort_values(ascending=False)\n",
+ ")\n",
+ "\n",
+ "highest_education = clv_segments.index[0][0]\n",
+ "highest_gender = clv_segments.index[0][1]\n",
+ "highest_value = clv_segments.iloc[0]\n",
+ "\n",
+ "lowest_education = clv_segments.index[-1][0]\n",
+ "lowest_gender = clv_segments.index[-1][1]\n",
+ "lowest_value = clv_segments.iloc[-1]\n",
+ "\n",
+ "print(\n",
+ " f\"The segment with the highest average customer lifetime \"\n",
+ " f\"value is {highest_gender} customers with \"\n",
+ " f\"{highest_education} education at {highest_value:,.2f}.\"\n",
+ ")\n",
+ "\n",
+ "print(\n",
+ " f\"The segment with the lowest average customer lifetime \"\n",
+ " f\"value is {lowest_gender} customers with \"\n",
+ " f\"{lowest_education} education at {lowest_value:,.2f}.\"\n",
+ ")\n",
+ "\n",
+ "gender_averages = (\n",
+ " df.groupby(\"gender\")\n",
+ " [\"customer_lifetime_value\"]\n",
+ " .mean()\n",
+ " .round(2)\n",
+ " .sort_values(ascending=False)\n",
+ " .to_frame(\"average_customer_lifetime_value\")\n",
+ ")\n",
+ "\n",
+ "print(\"\\nOverall average customer lifetime value by gender\")\n",
+ "\n",
+ "display(\n",
+ " gender_averages\n",
+ ")"
]
},
{
@@ -130,15 +1655,268 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 5,
"id": "3a069e0b-b400-470e-904d-d17582191be4",
"metadata": {
"id": "3a069e0b-b400-470e-904d-d17582191be4"
},
- "outputs": [],
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " Policy Type | \n",
+ " Month | \n",
+ " Number of Complaints | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " Corporate Auto | \n",
+ " January | \n",
+ " 443 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " Corporate Auto | \n",
+ " February | \n",
+ " 385 | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " Personal Auto | \n",
+ " January | \n",
+ " 1728 | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " Personal Auto | \n",
+ " February | \n",
+ " 1454 | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " Special Auto | \n",
+ " January | \n",
+ " 87 | \n",
+ "
\n",
+ " \n",
+ " | 5 | \n",
+ " Special Auto | \n",
+ " February | \n",
+ " 95 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " Policy Type Month Number of Complaints\n",
+ "0 Corporate Auto January 443\n",
+ "1 Corporate Auto February 385\n",
+ "2 Personal Auto January 1728\n",
+ "3 Personal Auto February 1454\n",
+ "4 Special Auto January 87\n",
+ "5 Special Auto February 95"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Month with the highest number of complaints for each policy type\n"
+ ]
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " Policy Type | \n",
+ " Month | \n",
+ " Number of Complaints | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " Corporate Auto | \n",
+ " January | \n",
+ " 443 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " Personal Auto | \n",
+ " January | \n",
+ " 1728 | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " Special Auto | \n",
+ " February | \n",
+ " 95 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " Policy Type Month Number of Complaints\n",
+ "0 Corporate Auto January 443\n",
+ "1 Personal Auto January 1728\n",
+ "2 Special Auto February 95"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "The highest complaint total was recorded for Personal Auto during January, with 1728 complaints.\n"
+ ]
+ }
+ ],
"source": [
- "# Your code goes here"
+ "df[\"effective_to_date\"] = pd.to_datetime(\n",
+ " df[\"effective_to_date\"],\n",
+ " errors=\"coerce\"\n",
+ ")\n",
+ "\n",
+ "df[\"number_of_open_complaints\"] = pd.to_numeric(\n",
+ " df[\"number_of_open_complaints\"],\n",
+ " errors=\"coerce\"\n",
+ ").fillna(0)\n",
+ "\n",
+ "month_order = [\n",
+ " \"January\",\n",
+ " \"February\",\n",
+ " \"March\",\n",
+ " \"April\",\n",
+ " \"May\",\n",
+ " \"June\",\n",
+ " \"July\",\n",
+ " \"August\",\n",
+ " \"September\",\n",
+ " \"October\",\n",
+ " \"November\",\n",
+ " \"December\"\n",
+ "]\n",
+ "\n",
+ "df[\"month\"] = pd.Categorical(\n",
+ " df[\"effective_to_date\"].dt.month_name(),\n",
+ " categories=month_order,\n",
+ " ordered=True\n",
+ ")\n",
+ "\n",
+ "complaints_long = (\n",
+ " df.groupby(\n",
+ " [\"policy_type\", \"month\"],\n",
+ " observed=True,\n",
+ " as_index=False\n",
+ " )\n",
+ " [\"number_of_open_complaints\"]\n",
+ " .sum()\n",
+ " .rename(\n",
+ " columns={\n",
+ " \"policy_type\": \"Policy Type\",\n",
+ " \"month\": \"Month\",\n",
+ " \"number_of_open_complaints\": \"Number of Complaints\"\n",
+ " }\n",
+ " )\n",
+ " .sort_values(\n",
+ " [\"Policy Type\", \"Month\"]\n",
+ " )\n",
+ " .reset_index(drop=True)\n",
+ ")\n",
+ "\n",
+ "complaints_long[\"Number of Complaints\"] = (\n",
+ " complaints_long[\"Number of Complaints\"]\n",
+ " .round()\n",
+ " .astype(int)\n",
+ ")\n",
+ "\n",
+ "display(\n",
+ " complaints_long\n",
+ ")\n",
+ "\n",
+ "highest_complaint_rows = (\n",
+ " complaints_long.loc[\n",
+ " complaints_long\n",
+ " .groupby(\"Policy Type\")\n",
+ " [\"Number of Complaints\"]\n",
+ " .idxmax()\n",
+ " ]\n",
+ " .sort_values(\"Policy Type\")\n",
+ " .reset_index(drop=True)\n",
+ ")\n",
+ "\n",
+ "print(\n",
+ " \"Month with the highest number of complaints \"\n",
+ " \"for each policy type\"\n",
+ ")\n",
+ "\n",
+ "display(\n",
+ " highest_complaint_rows\n",
+ ")\n",
+ "\n",
+ "overall_highest = complaints_long.loc[\n",
+ " complaints_long[\"Number of Complaints\"].idxmax()\n",
+ "]\n",
+ "\n",
+ "print(\n",
+ " f\"The highest complaint total was recorded for \"\n",
+ " f\"{overall_highest['Policy Type']} during \"\n",
+ " f\"{overall_highest['Month']}, with \"\n",
+ " f\"{overall_highest['Number of Complaints']} complaints.\"\n",
+ ")"
]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "af4a9169-da9a-497a-bc22-5f79ac53225f",
+ "metadata": {},
+ "outputs": [],
+ "source": []
}
],
"metadata": {
@@ -160,7 +1938,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.9.13"
+ "version": "3.13.14"
}
},
"nbformat": 4,