diff --git a/lab-dw-data-cleaning-and-formatting.ipynb b/lab-dw-data-cleaning-and-formatting.ipynb new file mode 100644 index 0000000..06fa4ec --- /dev/null +++ b/lab-dw-data-cleaning-and-formatting.ipynb @@ -0,0 +1,1711 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "25d7736c-ba17-4aff-b6bb-66eba20fbf4e", + "metadata": { + "id": "25d7736c-ba17-4aff-b6bb-66eba20fbf4e" + }, + "source": [ + "# Lab | Data Cleaning and Formatting" + ] + }, + { + "cell_type": "markdown", + "id": "d1973e9e-8be6-4039-b70e-d73ee0d94c99", + "metadata": { + "id": "d1973e9e-8be6-4039-b70e-d73ee0d94c99" + }, + "source": [ + "In this lab, we will be working with the customer data from an insurance company, which can be found in the CSV file located at the following link: https://raw.githubusercontent.com/data-bootcamp-v4/data/main/file1.csv\n" + ] + }, + { + "cell_type": "markdown", + "id": "31b8a9e7-7db9-4604-991b-ef6771603e57", + "metadata": { + "id": "31b8a9e7-7db9-4604-991b-ef6771603e57" + }, + "source": [ + "# Challenge 1: Data Cleaning and Formatting" + ] + }, + { + "cell_type": "markdown", + "id": "81553f19-9f2c-484b-8940-520aff884022", + "metadata": { + "id": "81553f19-9f2c-484b-8940-520aff884022" + }, + "source": [ + "## Exercise 1: Cleaning Column Names" + ] + }, + { + "cell_type": "markdown", + "id": "34a929f4-1be4-4fa8-adda-42ffd920be90", + "metadata": { + "id": "34a929f4-1be4-4fa8-adda-42ffd920be90" + }, + "source": [ + "To ensure consistency and ease of use, standardize the column names of the dataframe. Start by taking a first look at the dataframe and identifying any column names that need to be modified. Use appropriate naming conventions and make sure that column names are descriptive and informative.\n", + "\n", + "*Hint*:\n", + "- *Column names should be in lower case*\n", + "- *White spaces in column names should be replaced by `_`*\n", + "- *`st` could be replaced for `state`*" + ] + }, + { + "cell_type": "code", + "execution_count": 74, + "id": "5810735c-8056-4442-bbf2-dda38d3e284a", + "metadata": { + "id": "5810735c-8056-4442-bbf2-dda38d3e284a" + }, + "outputs": [], + "source": [ + "import numpy as np\n", + "import pandas as pd" + ] + }, + { + "cell_type": "code", + "execution_count": 75, + "id": "2fe76a07", + "metadata": {}, + "outputs": [], + "source": [ + "customer_data_insurance_df = pd.read_csv(\"Customer_data.csv\")" + ] + }, + { + "cell_type": "code", + "execution_count": 76, + "id": "48447f45", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
CustomerSTGENDEREducationCustomer Lifetime ValueIncomeMonthly Premium AutoNumber of Open ComplaintsPolicy TypeVehicle ClassTotal Claim Amount
0RB50392WashingtonNaNMasterNaN0.01000.01/0/00Personal AutoFour-Door Car2.704934
1QZ44356ArizonaFBachelor697953.59%0.094.01/0/00Personal AutoFour-Door Car1131.464935
2AI49188NevadaFBachelor1288743.17%48767.0108.01/0/00Personal AutoTwo-Door Car566.472247
3WW63253CaliforniaMBachelor764586.18%0.0106.01/0/00Corporate AutoSUV529.881344
4GA49547WashingtonMHigh School or Below536307.65%36357.068.01/0/00Personal AutoFour-Door Car17.269323
\n", + "
" + ], + "text/plain": [ + " Customer ST GENDER Education Customer Lifetime Value \\\n", + "0 RB50392 Washington NaN Master NaN \n", + "1 QZ44356 Arizona F Bachelor 697953.59% \n", + "2 AI49188 Nevada F Bachelor 1288743.17% \n", + "3 WW63253 California M Bachelor 764586.18% \n", + "4 GA49547 Washington M High School or Below 536307.65% \n", + "\n", + " Income Monthly Premium Auto Number of Open Complaints Policy Type \\\n", + "0 0.0 1000.0 1/0/00 Personal Auto \n", + "1 0.0 94.0 1/0/00 Personal Auto \n", + "2 48767.0 108.0 1/0/00 Personal Auto \n", + "3 0.0 106.0 1/0/00 Corporate Auto \n", + "4 36357.0 68.0 1/0/00 Personal Auto \n", + "\n", + " Vehicle Class Total Claim Amount \n", + "0 Four-Door Car 2.704934 \n", + "1 Four-Door Car 1131.464935 \n", + "2 Two-Door Car 566.472247 \n", + "3 SUV 529.881344 \n", + "4 Four-Door Car 17.269323 " + ] + }, + "execution_count": 76, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "customer_data_insurance_df.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 77, + "id": "f85a184c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Customer 2937\n", + "ST 2937\n", + "GENDER 3054\n", + "Education 2937\n", + "Customer Lifetime Value 2940\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\n", + "dtype: int64" + ] + }, + "execution_count": 77, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "customer_data_insurance_df.isnull().sum()" + ] + }, + { + "cell_type": "code", + "execution_count": 78, + "id": "bfb6a294", + "metadata": {}, + "outputs": [], + "source": [ + "customer_data_insurance_clean_df = customer_data_insurance_df.copy()" + ] + }, + { + "cell_type": "code", + "execution_count": 79, + "id": "f229d4f5", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Index(['Customer', 'ST', 'GENDER', 'Education', 'Customer Lifetime Value',\n", + " 'Income', 'Monthly Premium Auto', 'Number of Open Complaints',\n", + " 'Policy Type', 'Vehicle Class', 'Total Claim Amount'],\n", + " dtype='str')" + ] + }, + "execution_count": 79, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "customer_data_insurance_clean_df.columns" + ] + }, + { + "cell_type": "code", + "execution_count": 80, + "id": "d2048ea2", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Index(['customer', 'st', 'gender', 'education', 'customer_lifetime_value',\n", + " 'income', 'monthly_premium_auto', 'number_of_open_complaints',\n", + " 'policy_type', 'vehicle_class', 'total_claim_amount'],\n", + " dtype='str')\n" + ] + } + ], + "source": [ + "customer_data_insurance_clean_df.columns = customer_data_insurance_clean_df.columns.str.lower().str.replace(' ', '_')\n", + "\n", + "print(customer_data_insurance_clean_df.columns)" + ] + }, + { + "cell_type": "code", + "execution_count": 81, + "id": "03083eae", + "metadata": {}, + "outputs": [], + "source": [ + "customer_data_insurance_clean_df = customer_data_insurance_clean_df.rename(columns={\"st\": \"state\"})" + ] + }, + { + "cell_type": "code", + "execution_count": 82, + "id": "fd99e324", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Index(['customer', 'state', 'gender', 'education', 'customer_lifetime_value',\n", + " 'income', 'monthly_premium_auto', 'number_of_open_complaints',\n", + " 'policy_type', 'vehicle_class', 'total_claim_amount'],\n", + " dtype='str')" + ] + }, + "execution_count": 82, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "customer_data_insurance_clean_df.columns" + ] + }, + { + "cell_type": "markdown", + "id": "9cb501ec-36ff-4589-b872-6252bb150316", + "metadata": { + "id": "9cb501ec-36ff-4589-b872-6252bb150316" + }, + "source": [ + "## Exercise 2: Cleaning invalid Values" + ] + }, + { + "cell_type": "markdown", + "id": "771fdcf3-8e20-4b06-9c24-3a93ba2b0909", + "metadata": { + "id": "771fdcf3-8e20-4b06-9c24-3a93ba2b0909" + }, + "source": [ + "The dataset contains columns with inconsistent and incorrect values that could affect the accuracy of our analysis. Therefore, we need to clean these columns to ensure that they only contain valid data.\n", + "\n", + "Note that this exercise will focus only on cleaning inconsistent values and will not involve handling null values (NaN or None).\n", + "\n", + "*Hint*:\n", + "- *Gender column contains various inconsistent values such as \"F\", \"M\", \"Femal\", \"Male\", \"female\", which need to be standardized, for example, to \"M\" and \"F\".*\n", + "- *State abbreviations be can replaced with its full name, for example \"AZ\": \"Arizona\", \"Cali\": \"California\", \"WA\": \"Washington\"*\n", + "- *In education, \"Bachelors\" could be replaced by \"Bachelor\"*\n", + "- *In Customer Lifetime Value, delete the `%` character*\n", + "- *In vehicle class, \"Sports Car\", \"Luxury SUV\" and \"Luxury Car\" could be replaced by \"Luxury\"*" + ] + }, + { + "cell_type": "code", + "execution_count": 83, + "id": "3f8ee5cb-50ab-48af-8a9f-9a389804033c", + "metadata": { + "id": "3f8ee5cb-50ab-48af-8a9f-9a389804033c" + }, + "outputs": [ + { + "data": { + "text/plain": [ + "\n", + "['Washington', 'Arizona', 'Nevada', 'California', 'Oregon',\n", + " 'Cali', 'AZ', 'WA', nan]\n", + "Length: 9, dtype: str" + ] + }, + "execution_count": 83, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "customer_data_insurance_clean_df[\"state\"].unique()" + ] + }, + { + "cell_type": "code", + "execution_count": 84, + "id": "4c70d295", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "['Washington', 'Arizona', 'Nevada', 'California', 'Oregon', nan]\n", + "Length: 6, dtype: str\n" + ] + } + ], + "source": [ + "state_conversion = {\n", + " 'Cali': 'California', 'AZ': 'Arizona', 'WA': 'Washington',\n", + " 'Washington': 'Washington', 'Arizona': 'Arizona', 'Nevada': 'Nevada', 'California': 'California', 'Oregon': 'Oregon'\n", + "}\n", + "\n", + "customer_data_insurance_clean_df[\"state\"] = customer_data_insurance_clean_df[\"state\"].map(state_conversion).fillna(customer_data_insurance_clean_df[\"state\"])\n", + "\n", + "print(customer_data_insurance_clean_df[\"state\"].unique())" + ] + }, + { + "cell_type": "code", + "execution_count": 85, + "id": "4bc6cd14", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\n", + "[nan, 'F', 'M', 'Femal', 'Male', 'female']\n", + "Length: 6, dtype: str" + ] + }, + "execution_count": 85, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "customer_data_insurance_clean_df[\"gender\"].unique()" + ] + }, + { + "cell_type": "code", + "execution_count": 86, + "id": "e4be64c5", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "[nan, 'F', 'M']\n", + "Length: 3, dtype: str\n" + ] + } + ], + "source": [ + "gender_conversion = {\n", + " \"Male\": \"M\", \"Female\": \"F\", \"Femal\": \"F\", \"female\" : \"F\"\n", + "}\n", + "\n", + "customer_data_insurance_clean_df[\"gender\"] = customer_data_insurance_clean_df[\"gender\"].map(gender_conversion).fillna(customer_data_insurance_clean_df[\"gender\"])\n", + "\n", + "print(customer_data_insurance_clean_df[\"gender\"].unique())" + ] + }, + { + "cell_type": "code", + "execution_count": 87, + "id": "eeeafeb5", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\n", + "[ 'Master', 'Bachelor', 'High School or Below',\n", + " 'College', 'Bachelors', 'Doctor',\n", + " nan]\n", + "Length: 7, dtype: str" + ] + }, + "execution_count": 87, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "customer_data_insurance_clean_df[\"education\"].unique()" + ] + }, + { + "cell_type": "code", + "execution_count": 88, + "id": "26745f53", + "metadata": {}, + "outputs": [], + "source": [ + "customer_data_insurance_clean_df[\"education\"] = customer_data_insurance_clean_df[\"education\"].replace({\n", + " \"Bachelors\": \"Bachelor\"\n", + "})" + ] + }, + { + "cell_type": "code", + "execution_count": 89, + "id": "b1f920af", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\n", + "['Master', 'Bachelor', 'High School or Below', 'College', 'Doctor', nan]\n", + "Length: 6, dtype: str" + ] + }, + "execution_count": 89, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "customer_data_insurance_clean_df[\"education\"].unique()" + ] + }, + { + "cell_type": "code", + "execution_count": 90, + "id": "78e38594", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\n", + "[ nan, '697953.59%', '1288743.17%', '764586.18%', '536307.65%',\n", + " '825629.78%', '538089.86%', '721610.03%', '2412750.40%', '738817.81%',\n", + " ...\n", + " '943891.56%', '1050677.17%', '421391.86%', '477368.64%', '544142.01%',\n", + " '284226.69%', '305955.03%', '2031499.76%', '323912.47%', '899704.02%']\n", + "Length: 1028, dtype: str" + ] + }, + "execution_count": 90, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "customer_data_insurance_clean_df[\"customer_lifetime_value\"].unique()" + ] + }, + { + "cell_type": "code", + "execution_count": 91, + "id": "2c79595a", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "customer str\n", + "state str\n", + "gender str\n", + "education str\n", + "customer_lifetime_value str\n", + "income float64\n", + "monthly_premium_auto float64\n", + "number_of_open_complaints str\n", + "policy_type str\n", + "vehicle_class str\n", + "total_claim_amount float64\n", + "dtype: object" + ] + }, + "execution_count": 91, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "customer_data_insurance_clean_df.dtypes" + ] + }, + { + "cell_type": "code", + "execution_count": 92, + "id": "cc7c9134", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\n", + "[ nan, '697953.59', '1288743.17', '764586.18', '536307.65',\n", + " '825629.78', '538089.86', '721610.03', '2412750.40', '738817.81',\n", + " ...\n", + " '943891.56', '1050677.17', '421391.86', '477368.64', '544142.01',\n", + " '284226.69', '305955.03', '2031499.76', '323912.47', '899704.02']\n", + "Length: 1028, dtype: str" + ] + }, + "execution_count": 92, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "customer_data_insurance_clean_df[\"customer_lifetime_value\"] = customer_data_insurance_clean_df[\"customer_lifetime_value\"].str.replace('%', '')\n", + "customer_data_insurance_clean_df[\"customer_lifetime_value\"].unique()" + ] + }, + { + "cell_type": "code", + "execution_count": 93, + "id": "530f55e7", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\n", + "['Four-Door Car', 'Two-Door Car', 'SUV', 'Luxury SUV',\n", + " 'Sports Car', 'Luxury Car', nan]\n", + "Length: 7, dtype: str" + ] + }, + "execution_count": 93, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "customer_data_insurance_clean_df[\"vehicle_class\"].unique()" + ] + }, + { + "cell_type": "code", + "execution_count": 94, + "id": "a0d81ec0", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\n", + "['Four-Door Car', 'Two-Door Car', 'SUV', 'Luxury', nan]\n", + "Length: 5, dtype: str" + ] + }, + "execution_count": 94, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "customer_data_insurance_clean_df[\"vehicle_class\"] = customer_data_insurance_clean_df[\"vehicle_class\"].replace(\n", + " {\"Sports Car\": \"Luxury\", \"Luxury SUV\": \"Luxury\", \"Luxury Car\": \"Luxury\"}\n", + ")\n", + "customer_data_insurance_clean_df[\"vehicle_class\"].unique()" + ] + }, + { + "cell_type": "markdown", + "id": "85ff78ce-0174-4890-9db3-8048b7d7d2d0", + "metadata": { + "id": "85ff78ce-0174-4890-9db3-8048b7d7d2d0" + }, + "source": [ + "## Exercise 3: Formatting data types" + ] + }, + { + "cell_type": "markdown", + "id": "b91c2cf8-79a2-4baf-9f65-ff2fb22270bd", + "metadata": { + "id": "b91c2cf8-79a2-4baf-9f65-ff2fb22270bd" + }, + "source": [ + "The data types of many columns in the dataset appear to be incorrect. This could impact the accuracy of our analysis. To ensure accurate analysis, we need to correct the data types of these columns. Please update the data types of the columns as appropriate." + ] + }, + { + "cell_type": "markdown", + "id": "43e5d853-ff9e-43b2-9d92-aef2f78764f3", + "metadata": { + "id": "43e5d853-ff9e-43b2-9d92-aef2f78764f3" + }, + "source": [ + "It is important to note that this exercise does not involve handling null values (NaN or None)." + ] + }, + { + "cell_type": "markdown", + "id": "329ca691-9196-4419-8969-3596746237a1", + "metadata": { + "id": "329ca691-9196-4419-8969-3596746237a1" + }, + "source": [ + "*Hint*:\n", + "- *Customer lifetime value should be numeric*\n", + "- *Number of open complaints has an incorrect format. Look at the different values it takes with `unique()` and take the middle value. As an example, 1/5/00 should be 5. Number of open complaints is a string - remember you can use `split()` to deal with it and take the number you need. Finally, since it should be numeric, cast the column to be in its proper type.*" + ] + }, + { + "cell_type": "code", + "execution_count": 95, + "id": "eb8f5991-73e9-405f-bf1c-6b7c589379a9", + "metadata": { + "id": "eb8f5991-73e9-405f-bf1c-6b7c589379a9" + }, + "outputs": [ + { + "data": { + "text/plain": [ + "customer str\n", + "state str\n", + "gender str\n", + "education str\n", + "customer_lifetime_value str\n", + "income float64\n", + "monthly_premium_auto float64\n", + "number_of_open_complaints str\n", + "policy_type str\n", + "vehicle_class str\n", + "total_claim_amount float64\n", + "dtype: object" + ] + }, + "execution_count": 95, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "customer_data_insurance_clean_df.dtypes" + ] + }, + { + "cell_type": "code", + "execution_count": 96, + "id": "362a916f", + "metadata": {}, + "outputs": [], + "source": [ + "customer_data_insurance_clean_df[\"customer_lifetime_value\"] = pd.to_numeric(customer_data_insurance_clean_df[\"customer_lifetime_value\"], errors='coerce')" + ] + }, + { + "cell_type": "code", + "execution_count": 97, + "id": "343fa313", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2940\n" + ] + } + ], + "source": [ + "print(customer_data_insurance_clean_df[\"customer_lifetime_value\"].isnull().sum())" + ] + }, + { + "cell_type": "code", + "execution_count": 98, + "id": "45263c76", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "customer str\n", + "state str\n", + "gender str\n", + "education str\n", + "customer_lifetime_value float64\n", + "income float64\n", + "monthly_premium_auto float64\n", + "number_of_open_complaints str\n", + "policy_type str\n", + "vehicle_class str\n", + "total_claim_amount float64\n", + "dtype: object" + ] + }, + "execution_count": 98, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "customer_data_insurance_clean_df.dtypes" + ] + }, + { + "cell_type": "code", + "execution_count": 99, + "id": "579b0f1f", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "['1/0/00', '1/2/00', '1/1/00', '1/3/00', '1/5/00', '1/4/00', nan]\n", + "Length: 7, dtype: str\n" + ] + } + ], + "source": [ + "print(customer_data_insurance_clean_df[\"number_of_open_complaints\"].unique())" + ] + }, + { + "cell_type": "code", + "execution_count": 100, + "id": "868b1682", + "metadata": {}, + "outputs": [], + "source": [ + "customer_data_insurance_clean_df[\"number_of_open_complaints\"] = customer_data_insurance_clean_df[\"number_of_open_complaints\"].apply(\n", + " lambda x: int(x.split('/')[1]) if pd.notnull(x) else x\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 101, + "id": "8dd0048b", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "number_of_open_complaints\n", + "0.0 830\n", + "1.0 138\n", + "2.0 50\n", + "3.0 34\n", + "4.0 13\n", + "5.0 6\n", + "Name: count, dtype: int64\n" + ] + } + ], + "source": [ + "print(customer_data_insurance_clean_df[\"number_of_open_complaints\"].value_counts())" + ] + }, + { + "cell_type": "code", + "execution_count": 102, + "id": "e7f1ea55", + "metadata": {}, + "outputs": [], + "source": [ + "customer_data_insurance_clean_df[\"number_of_open_complaints\"] = pd.to_numeric(customer_data_insurance_clean_df[\"number_of_open_complaints\"], errors='coerce')" + ] + }, + { + "cell_type": "code", + "execution_count": 103, + "id": "893211f7", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "customer str\n", + "state str\n", + "gender str\n", + "education str\n", + "customer_lifetime_value float64\n", + "income float64\n", + "monthly_premium_auto float64\n", + "number_of_open_complaints float64\n", + "policy_type str\n", + "vehicle_class str\n", + "total_claim_amount float64\n", + "dtype: object" + ] + }, + "execution_count": 103, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "customer_data_insurance_clean_df.dtypes" + ] + }, + { + "cell_type": "code", + "execution_count": 104, + "id": "f8a908f3", + "metadata": {}, + "outputs": [], + "source": [ + "customer_data_insurance_clean_df[\"number_of_open_complaints\"] = customer_data_insurance_clean_df[\"number_of_open_complaints\"].astype(pd.Int64Dtype())" + ] + }, + { + "cell_type": "code", + "execution_count": 105, + "id": "a6accff4", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "customer str\n", + "state str\n", + "gender str\n", + "education str\n", + "customer_lifetime_value float64\n", + "income float64\n", + "monthly_premium_auto float64\n", + "number_of_open_complaints Int64\n", + "policy_type str\n", + "vehicle_class str\n", + "total_claim_amount float64\n", + "dtype: object" + ] + }, + "execution_count": 105, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "customer_data_insurance_clean_df.dtypes" + ] + }, + { + "cell_type": "markdown", + "id": "14c52e28-2d0c-4dd2-8bd5-3476e34fadc1", + "metadata": { + "id": "14c52e28-2d0c-4dd2-8bd5-3476e34fadc1" + }, + "source": [ + "## Exercise 4: Dealing with Null values" + ] + }, + { + "cell_type": "markdown", + "id": "34b9a20f-7d32-4417-975e-1b4dfb0e16cd", + "metadata": { + "id": "34b9a20f-7d32-4417-975e-1b4dfb0e16cd" + }, + "source": [ + "Identify any columns with null or missing values. Identify how many null values each column has. You can use the `isnull()` function in pandas to find columns with null values.\n", + "\n", + "Decide on a strategy for handling the null values. There are several options, including:\n", + "\n", + "- Drop the rows or columns with null values\n", + "- Fill the null values with a specific value (such as the column mean or median for numerical variables, and mode for categorical variables)\n", + "- Fill the null values with the previous or next value in the column\n", + "- Fill the null values based on a more complex algorithm or model (note: we haven't covered this yet)\n", + "\n", + "Implement your chosen strategy to handle the null values. You can use the `fillna()` function in pandas to fill null values or `dropna()` function to drop null values.\n", + "\n", + "Verify that your strategy has successfully handled the null values. You can use the `isnull()` function again to check if there are still null values in the dataset.\n", + "\n", + "Remember to document your process and explain your reasoning for choosing a particular strategy for handling null values.\n", + "\n", + "After formatting data types, as a last step, convert all the numeric variables to integers." + ] + }, + { + "cell_type": "code", + "execution_count": 106, + "id": "f184fc35-7831-4836-a0a5-e7f99e01b40e", + "metadata": { + "id": "f184fc35-7831-4836-a0a5-e7f99e01b40e" + }, + "outputs": [ + { + "data": { + "text/plain": [ + "customer 2937\n", + "state 2937\n", + "gender 3054\n", + "education 2937\n", + "customer_lifetime_value 2940\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\n", + "dtype: int64" + ] + }, + "execution_count": 106, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "customer_data_insurance_clean_df.isnull().sum()" + ] + }, + { + "cell_type": "code", + "execution_count": 107, + "id": "0c3517e3", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Number of entirely empty rows: 2937\n" + ] + } + ], + "source": [ + "empty_rows = customer_data_insurance_clean_df.isnull().all(axis=1)\n", + "print(\"Number of entirely empty rows:\", empty_rows.sum())" + ] + }, + { + "cell_type": "code", + "execution_count": 108, + "id": "7327fee5", + "metadata": {}, + "outputs": [], + "source": [ + "#Dropping the rows that are entirely empty.\n", + "customer_data_insurance_clean_df = customer_data_insurance_clean_df.dropna(axis=0, how=\"all\")" + ] + }, + { + "cell_type": "code", + "execution_count": 109, + "id": "05f39904", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Number of entirely empty rows: 0\n" + ] + } + ], + "source": [ + "empty_rows = customer_data_insurance_clean_df.isnull().all(axis=1)\n", + "print(\"Number of entirely empty rows:\", empty_rows.sum())" + ] + }, + { + "cell_type": "code", + "execution_count": 110, + "id": "db74f313", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Number of entirely empty columns: 0\n" + ] + } + ], + "source": [ + "empty_columns = customer_data_insurance_clean_df.isnull().all(axis=0)\n", + "print(\"Number of entirely empty columns:\", empty_columns.sum())" + ] + }, + { + "cell_type": "code", + "execution_count": 111, + "id": "15c5f17a", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "customer 0\n", + "state 0\n", + "gender 117\n", + "education 0\n", + "customer_lifetime_value 3\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\n", + "dtype: int64" + ] + }, + "execution_count": 111, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "customer_data_insurance_clean_df.isnull().sum()" + ] + }, + { + "cell_type": "code", + "execution_count": 112, + "id": "17566ef3", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " customer state gender education \\\n", + "0 RB50392 Washington NaN Master \n", + "78 SP81997 Washington F Master \n", + "988 GT62080 Washington M High School or Below \n", + "\n", + " customer_lifetime_value income monthly_premium_auto \\\n", + "0 NaN 0.0 1000.0 \n", + "78 NaN 41275.0 96.0 \n", + "988 NaN 55561.0 63.0 \n", + "\n", + " number_of_open_complaints policy_type vehicle_class \\\n", + "0 0 Personal Auto Four-Door Car \n", + "78 0 Personal Auto Four-Door Car \n", + "988 0 Personal Auto Four-Door Car \n", + "\n", + " total_claim_amount \n", + "0 2.704934 \n", + "78 41.122303 \n", + "988 227.872071 \n" + ] + } + ], + "source": [ + "#Only gender and customer lifetime value have nulls.\n", + "null_clv_rows = customer_data_insurance_clean_df[customer_data_insurance_clean_df[\"customer_lifetime_value\"].isna()]\n", + "print(null_clv_rows)" + ] + }, + { + "cell_type": "code", + "execution_count": 113, + "id": "4221f340", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjsAAAHFCAYAAAAUpjivAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjksIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvJkbTWQAAAAlwSFlzAAAPYQAAD2EBqD+naQAAQ7BJREFUeJzt3Xd8VFX+//H3kDIJSQgkIe1LCJEmkoAISlOKNEMvu4ioFEFh6QKLgqtElyWKUlxdsKwGEBAbqIgFkCII+5MiUpcm3cQgQgIBEkjO7w8ezDokgTAZnOT6ej4e96H33DPnfu5lSN6cufeOzRhjBAAAYFFlPF0AAADAzUTYAQAAlkbYAQAAlkbYAQAAlkbYAQAAlkbYAQAAlkbYAQAAlkbYAQAAlkbYAQAAlkbYwU0xe/Zs2Ww2x+Ln56fIyEi1bNlSycnJSk9Pz/eapKQk2Wy2G9rPuXPnlJSUpNWrV9/Q6wraV5UqVdSxY8cbGud6FixYoBkzZhS4zWazKSkpya37c7evv/5aDRo0UEBAgGw2mz7++ONr9v/555/15JNPKiEhQYGBgfLz81P16tU1cuRI7du376bUuGvXLiUlJenQoUM3ZXxPK8r7sl+/fqpSpYpT26+//qpevXopPDxcNptNXbt2vaH9zpw5U7Nnz87XfujQIdlstgK3/d4uXryoiIgINWrUqNA+eXl5qly5surUqVPkcVevXi2bzXbDP1dQcnl7ugBYW0pKim699VZdvHhR6enpWrdunV544QW99NJLeu+999S6dWtH34EDB+q+++67ofHPnTunZ599VpLUokWLIr/OlX25YsGCBdqxY4dGjRqVb9uGDRtUqVKlm16Dq4wx6tmzp2rUqKFPP/1UAQEBqlmzZqH9v/vuO3Xs2FHGGA0bNkyNGzeWr6+v9uzZo3nz5umuu+7SqVOn3F7nrl279Oyzz6pFixb5fuH/UTz99NMaOXKkU9vf//53LV68WG+//baqVq2qkJCQGxpz5syZCgsLU79+/Zzao6KitGHDBlWtWrW4ZRebj4+PHn74YU2dOlW7du3Sbbfdlq/PihUrdPToUY0ZM8YDFaKkIOzgpoqPj1eDBg0c6z169NDjjz+uu+++W927d9e+ffsUEREhSapUqdJN/+V/7tw5lS1b9nfZ1/Vc61+jJcFPP/2kX3/9Vd26dVOrVq2u2TczM1NdunSRn5+f1q9f73RuW7RooUGDBunDDz+82SWXSrm5ubp06ZLsdrvLYxQUPHbs2KGqVavqwQcfLE55+djt9hL13h0wYICmTp2qt99+Wy+99FK+7W+//bZ8fX310EMPeaA6lBgGuAlSUlKMJLNx48YCt7///vtGknn22WcdbRMnTjRXvyW//vpr07x5cxMSEmL8/PxMTEyM6d69u8nKyjIHDx40kvItffv2dRpv8+bNpkePHqZ8+fImMjKy0H3FxsaaDh06mEWLFpmEhARjt9tNXFycefnllws8toMHDzq1r1q1ykgyq1atMsYY07x58wLru0KSmThxotMY27dvN507dzbly5c3drvd1K1b18yePbvA/SxYsMBMmDDBREVFmaCgINOqVSvz3//+t8DzfbW1a9eae++91wQGBhp/f3/TuHFj89lnn+X7s/jtEhsbW+h4L730kpFk3n333SLtv3nz5qZ58+b52vv27ZtvPzNnzjR16tQxAQEBJjAw0NSsWdOMHz/eGPO/P4url5SUFMfr33rrLVOnTh1jt9tNhQoVTNeuXc2uXbvy7TcgIMDs3r3btG3b1pQtW9ZERkaa5ORkY4wxGzZsME2bNjVly5Y11atXz/dnYowxqamp5rHHHjP/93//Z3x8fEyVKlVMUlKSuXjxoqPPlffsCy+8YP7+97+bKlWqGC8vL/PFF18Ueq6uvC+v5bfnrbC/F1fel9nZ2ebvf/+7qVmzpvH19TVhYWGmX79+Jj093Wmfhf35Xxn/t+f4yvvlhx9+MH/6059MuXLlTIUKFczjjz9uLl68aP773/+adu3amcDAQBMbG2teeOGFfMeQkZFhxowZY6pUqWJ8fHxMdHS0GTlypDl79uw1j90YYxo3bmzCw8OdzrUxxpw6dcr4+fmZP//5z8YYYzZu3Gjuv/9+Exsba/z8/ExsbKzp1auXOXTokNPrrv67bMyNvWeLco7x+2JmBx7Rvn17eXl56Ztvvim0z6FDh9ShQwfdc889evvtt1W+fHkdP35cX375pXJychQVFaUvv/xS9913nwYMGKCBAwdKkipWrOg0Tvfu3dWrVy8NHjxYWVlZ16xr69atGjVqlJKSkhQZGan58+dr5MiRysnJ0dixY2/oGGfOnKnHHntMBw4c0OLFi6/bf8+ePWrSpInCw8P1z3/+U6GhoZo3b5769eun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O2Z7IiMjlZOTo1OnThXa52p2u13lypVzWgAAgDV5NOwYYzRs2DAtWrRIK1euVFxcnNP2uLg4RUZGavny5Y62nJwcrVmzRk2aNJEk1a9fXz4+Pk59UlNTtWPHDkcfAADwx+XtyZ0PHTpUCxYs0CeffKKgoCDHDE5wcLD8/f1ls9k0atQoTZ48WdWrV1f16tU1efJklS1bVr1793b0HTBggMaMGaPQ0FCFhIRo7NixSkhIUOvWrT15eAAAoATwaNiZNWuWJKlFixZO7SkpKerXr58kady4cTp//ryGDBmiU6dOqWHDhlq2bJmCgoIc/adPny5vb2/17NlT58+fV6tWrTR79mx5eXn9XocCAABKqBL1nB1P4Tk7AACUPqXyOTsAAADuRtgBAACWRtgBAACWRtgBAACWRtgBAACWRtgBAACWRtgBAACWRtgBAACWRtgBAACWRtgBAACWRtgBAACWRtgBAACWRtgBAACWRtgBAACWRtgBAACWRtgBAACWRtgBAACWRtgBAACWRtgBAACWRtgBAACWRtgBAACWRtgBAACWRtgBAACWRtgBAACWRtgBAACWRtgBAACWRtgBAACWRtgBAACWRtgBAACWRtgBAACWRtgBAACWRtgBAACW5u3pAlAyVXlyqcuvPfR8BzdWAgBA8TCzAwAALI2wAwAALI2wAwAALM2lsHPw4EF31wEAAHBTuBR2qlWrppYtW2revHm6cOGCu2sCAABwG5fCzg8//KB69eppzJgxioyM1KBBg/Tdd9+5uzYAAIBicynsxMfHa9q0aTp+/LhSUlKUlpamu+++W7Vr19a0adN04sQJd9cJAADgkmJdoOzt7a1u3brp/fff1wsvvKADBw5o7NixqlSpkvr06aPU1FR31QkAAOCSYoWdTZs2aciQIYqKitK0adM0duxYHThwQCtXrtTx48fVpUsXd9UJAADgEpeeoDxt2jSlpKRoz549at++vebOnav27durTJnL2SkuLk6vv/66br31VrcWCwAAcKNcCjuzZs3SI488ov79+ysyMrLAPpUrV9Zbb71VrOIAAACKy6Wws2/fvuv28fX1Vd++fV0ZHgAAwG1cumYnJSVFH3zwQb72Dz74QHPmzCl2UQAAAO7iUth5/vnnFRYWlq89PDxckydPLnZRAAAA7uJS2Dl8+LDi4uLytcfGxurIkSPFLgoAAMBdXAo74eHh2rZtW772H374QaGhocUuCgAAwF1cCju9evXSiBEjtGrVKuXm5io3N1crV67UyJEj1atXL3fXCAAA4DKX7saaNGmSDh8+rFatWsnb+/IQeXl56tOnD9fsAACAEsWlsOPr66v33ntPf//73/XDDz/I399fCQkJio2NdXd9AAAAxeJS2LmiRo0aqlGjhrtqAQAAcDuXwk5ubq5mz56tr7/+Wunp6crLy3PavnLlSrcUBwAAUFwuXaA8cuRIjRw5Urm5uYqPj1fdunWdlqL65ptv1KlTJ0VHR8tms+njjz922t6vXz/ZbDanpVGjRk59srOzNXz4cIWFhSkgIECdO3fWsWPHXDksAABgQS7N7CxcuFDvv/++2rdvX6ydZ2VlqW7duurfv7969OhRYJ/77rtPKSkpjnVfX1+n7aNGjdKSJUu0cOFChYaGasyYMerYsaM2b94sLy+vYtUHAABKP5cvUK5WrVqxd56YmKjExMRr9rHb7YV+2WhGRobeeustvfPOO2rdurUkad68eYqJidGKFSvUrl27YtcIAABKN5c+xhozZoxefvllGWPcXU8+q1evVnh4uGrUqKFHH31U6enpjm2bN2/WxYsX1bZtW0dbdHS04uPjtX79+kLHzM7OVmZmptMCAACsyaWZnXXr1mnVqlX64osvVLt2bfn4+DhtX7RokVuKS0xM1J///GfFxsbq4MGDevrpp3Xvvfdq8+bNstvtSktLk6+vrypUqOD0uoiICKWlpRU6bnJysp599lm31AgAAEo2l8JO+fLl1a1bN3fXks/999/v+P/4+Hg1aNBAsbGxWrp0qbp3717o64wxstlshW4fP368Ro8e7VjPzMxUTEyMe4oGAAAlikth57cXDP+eoqKiFBsbq3379kmSIiMjlZOTo1OnTjnN7qSnp6tJkyaFjmO322W32296vQAAwPNcumZHki5duqQVK1bo9ddf15kzZyRJP/30k86ePeu24q528uRJHT16VFFRUZKk+vXry8fHR8uXL3f0SU1N1Y4dO64ZdgAAwB+HSzM7hw8f1n333acjR44oOztbbdq0UVBQkKZMmaILFy7otddeK9I4Z8+e1f79+x3rBw8e1NatWxUSEqKQkBAlJSWpR48eioqK0qFDhzRhwgSFhYU5PkILDg7WgAEDNGbMGIWGhiokJERjx45VQkKC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52bnzp2mb9++pkKFCubkyZPGmP99uWujRo3MunXrzJYtW0y1atVM8+bNTdu2bc2WLVvMN998Y0JDQ83zzz/vqG3ChAnm1ltvNV9++aU5cOCASUlJMXa73axevdpp3Dp16phly5aZ/fv3m19++eWa52bixImmbt26jvW+ffuaLl26GGOMOX36tHnuuedMpUqVTGpqqklPT79uHdc6L1d/AWZsbKwJCQkxr732mtm7d6/5y1/+YoKCgsx9991n3n//fbNnzx7TtWtXU6tWLZOXl2eMMWbbtm0mMDDQTJ8+3ezdu9d8++23pl69eqZfv37XfR9s377dSDL79+93tO3YscNRqzHGfP311+add94xu3btMrt27TIDBgwwERERJjMz0/EaSWbx4sVO5/xa76Hi1AwU5LfvQWOM2b9/v7HZbOb48eNO/Vq1amXGjx9vjDFm0KBBxm63m4YNG5pvvvnGrFq1ytx+++2mZcuWN7bvYlcPwO0yMzON3W43b775Zr5tRflFlZCQYJKSkgocu6DXnz171vj4+Jj58+c72nJyckx0dLSZMmWK0+tWrFjh6JOcnGwkmQMHDjjaBg0aZNq1a+cY18/Pz6xfv96phgEDBpgHHnjAadyPP/64CGfmsmuFHWOMmT59uomNjXU6vqLW8dvzYkzBYeehhx5yrKemphpJ5umnn3a0bdiwwUgyqampxhhjHn74YfPYY485jbt27VpTpkwZc/78+eseb506dcxzzz3nWB8/fry58847C+1/6dIlExQUZJYsWeJou9GwU9yagatdHXbef/99I8kEBAQ4Ld7e3qZnz57GGGMeffRRp2BvjDGbN282ksx///vfIu+ba3aAEmj37t3Kzs5Wq1atXHr9iBEj9Je//EXLli1T69at1aNHD9WpU6fQ/gcOHNDFixfVtGlTR5uPj4/uuusu7d6926nvb8eJiIhQ2bJldcsttzi1fffdd5KkXbt26cKFC2rTpo3TGDk5OapXr55TW4MGDW78QIvoRuooiqvPgSQlJCTka0tPT1dkZKQ2b96s/fv3a/78+Y4+xhjl5eXp4MGDqlWr1jX39+CDD+rtt9/W008/LWOM3n33XaeP1tLT0/XMM89o5cqV+vnnn5Wbm6tz587pyJEjN3xsVxS3ZuB68vLy5OXlpc2bN8vLy8tpW2BgoCQpKipK3t7eqlGjhmPblffekSNHinwdD2EHKIH8/f0L3VamzOVL7cxv7j66ePGiU5+BAweqXbt2Wrp0qZYtW6bk5GRNnTpVw4cPL3DMK2PZbLZ87Ve3/fbOJJvNlu9OJZvNpry8PEly/Hfp0qX6v//7P6d+drvdaT0gIKDA2tzhRuooiqvPQWFtvz0PgwYN0ogRI/KNVbly5evur3fv3nryySe1ZcsWnT9/XkePHlWvXr0c2/v166cTJ05oxowZio2Nld1uV+PGjZWTk1PgeEV5DxW3ZuB66tWrp9zcXKWnp+uee+4psE/Tpk116dIlHThwQFWrVpUk7d27V5IUGxtb5H0RdoASqHr16vL399fXX3+tgQMHOm2rWLGiJCk1NVUVKlSQpAKfIxMTE6PBgwdr8ODBGj9+vN58800NHz5cvr6+kqTc3FxH32rVqsnX11fr1q1T7969JV3+5bdp06ZiPWPmtttuk91u15EjR9S8eXOXxymuotRR0HlxlzvuuEM7d+5UtWrVXHp9pUqV1KxZM82fP1/nz59X69atHbNHkrR27VrNnDlT7du3lyQdPXr0mrfmFuU9VNyaAUk6e/as9u/f71g/ePCgtm7dqpCQENWoUUMPPvig+vTpo6lTp6pevXr65ZdftHLlSiUkJKh9+/Zq3bq17rjjDj3yyCOaMWOG8vLyNHToULVp08Zptud6CDtACeTn56cnnnhC48aNk6+vr5o2baoTJ05o586d6tOnj2JiYpSUlKRJkyZp3759mjp1qtPrR40apcTERNWoUUOnTp3SypUrHVO/sbGxstls+uyzz9S+fXv5+/srMDBQf/nLX/TXv/5VISEhqly5sqZMmaJz585pwIABLh9HUFCQxo4dq8cff1x5eXm6++67lZmZqfXr1yswMFB9+/Yt1nlyZx2FnRd3eOKJJ9SoUSMNHTpUjz76qAICArR7924tX75cr7zySpHGePDBB5WUlKScnBxNnz7daVu1atX0zjvvqEGDBsrMzNRf//rXa84OVqtW7brvIXfUDGzatMlxp6MkjR49WpLUt29fzZ49WykpKZo0aZLGjBmj48ePKzQ0VI0bN3YE9zJlymjJkiUaPny4mjVrpoCAACUmJuZ7v15X8S85AnAz5ObmmkmTJpnY2Fjj4+NjKleubCZPnmyMMWbdunUmISHB+Pn5mXvuucd88MEHTheXDhs2zFStWtXY7XZTsWJF8/DDDzvd4fTcc8+ZyMhIY7PZTN++fY0xxpw/f94MHz7chIWFGbvdbpo2bWq+++47x2sKuqg1JSXFBAcHO9V99cXDeXl55uWXXzY1a9Y0Pj4+pmLFiqZdu3ZmzZo1hY57PTd6gXJR6ijsvBR0gfL06dOdxtZVF14ePHjQSDLff/+9o+27774zbdq0MYGBgSYgIMDUqVPH/OMf/yjyMZ86dcrY7XZTtmxZc+bMGadtW7ZsMQ0aNDB2u91Ur17dfPDBB/nqvLrG672H3FEzUFLYjPnNh7YAAAAWw0MFAQCApRF2AJQ4tWvXVmBgYIHLb2+FtoK1a9cWeqzuumYI+KPjYywAJc7hw4fz3Qp9RUREhIKCgn7nim6e8+fP6/jx44Vu524ooPgIOwAAwNL4GAsAAFgaYQcAAFgaYQcAAFgaYQcAAFgaYQcAAFgaYQcAAFgaYQcAAFgaYQcAAFja/wdKu/7+4+K3IwAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "#Let's check the distribution of customer lifetime value\n", + "import matplotlib.pyplot as plt\n", + "\n", + "customer_data_insurance_clean_df[\"customer_lifetime_value\"].plot(kind=\"hist\", bins=30, title=\"Distribution of Customer Lifetime Value\")\n", + "plt.xlabel(\"customer_lifetime_value\")\n", + "plt.ylabel(\"Frequency\")\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 114, + "id": "b13d6fae", + "metadata": {}, + "outputs": [], + "source": [ + "#Since the distribution is skewed and have some outliers, we will use the median to fill the nulls.\n", + "median_value = customer_data_insurance_clean_df[\"customer_lifetime_value\"].median()" + ] + }, + { + "cell_type": "code", + "execution_count": 115, + "id": "6c4c295a", + "metadata": {}, + "outputs": [], + "source": [ + "customer_data_insurance_clean_df[\"customer_lifetime_value\"] = customer_data_insurance_clean_df[\"customer_lifetime_value\"].fillna(median_value)" + ] + }, + { + "cell_type": "code", + "execution_count": 116, + "id": "f2e9eccf", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "customer 0\n", + "state 0\n", + "gender 117\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\n", + "dtype: int64" + ] + }, + "execution_count": 116, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "customer_data_insurance_clean_df.isnull().sum()" + ] + }, + { + "cell_type": "code", + "execution_count": 117, + "id": "0aa5b9c1", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "RangeIndex: 1071 entries, 0 to 1070\n", + "Data columns (total 11 columns):\n", + " # Column Non-Null Count Dtype \n", + "--- ------ -------------- ----- \n", + " 0 customer 1071 non-null str \n", + " 1 state 1071 non-null str \n", + " 2 gender 954 non-null str \n", + " 3 education 1071 non-null str \n", + " 4 customer_lifetime_value 1071 non-null float64\n", + " 5 income 1071 non-null float64\n", + " 6 monthly_premium_auto 1071 non-null float64\n", + " 7 number_of_open_complaints 1071 non-null Int64 \n", + " 8 policy_type 1071 non-null str \n", + " 9 vehicle_class 1071 non-null str \n", + " 10 total_claim_amount 1071 non-null float64\n", + "dtypes: Int64(1), float64(4), str(6)\n", + "memory usage: 146.3 KB\n" + ] + } + ], + "source": [ + "customer_data_insurance_clean_df.info()" + ] + }, + { + "cell_type": "code", + "execution_count": 118, + "id": "8a688e3f", + "metadata": {}, + "outputs": [], + "source": [ + "#We do not have any reference for the gender nulls, so we will fill the nulls with \"unknown\".\n", + "customer_data_insurance_clean_df[\"gender\"] = customer_data_insurance_clean_df[\"gender\"].fillna(\"Unknown\")" + ] + }, + { + "cell_type": "code", + "execution_count": 119, + "id": "0487b685", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "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\n", + "dtype: int64" + ] + }, + "execution_count": 119, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "customer_data_insurance_clean_df.isnull().sum()" + ] + }, + { + "cell_type": "markdown", + "id": "98416351-e999-4156-9834-9b00a311adfa", + "metadata": { + "id": "98416351-e999-4156-9834-9b00a311adfa" + }, + "source": [ + "## Exercise 5: Dealing with duplicates" + ] + }, + { + "cell_type": "markdown", + "id": "ea0816a7-a18e-4d4c-b667-a8452a800bd1", + "metadata": { + "id": "ea0816a7-a18e-4d4c-b667-a8452a800bd1" + }, + "source": [ + "Use the `.duplicated()` method to identify any duplicate rows in the dataframe.\n", + "\n", + "Decide on a strategy for handling the duplicates. Options include:\n", + "- Dropping all duplicate rows\n", + "- Keeping only the first occurrence of each duplicated row\n", + "- Keeping only the last occurrence of each duplicated row\n", + "- Dropping duplicates based on a subset of columns\n", + "- Dropping duplicates based on a specific column\n", + "\n", + "Implement your chosen strategy using the `drop_duplicates()` function.\n", + "\n", + "Verify that your strategy has successfully handled the duplicates by checking for duplicates again using `.duplicated()`.\n", + "\n", + "Remember to document your process and explain your reasoning for choosing a particular strategy for handling duplicates.\n", + "\n", + "Save the cleaned dataset to a new CSV file.\n", + "\n", + "*Hint*: *after dropping duplicates, reset the index to ensure consistency*." + ] + }, + { + "cell_type": "code", + "execution_count": 120, + "id": "1929362c-47ed-47cb-baca-358b78d401a0", + "metadata": { + "id": "1929362c-47ed-47cb-baca-358b78d401a0" + }, + "outputs": [ + { + "data": { + "text/plain": [ + "np.int64(0)" + ] + }, + "execution_count": 120, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "customer_data_insurance_clean_df.duplicated().sum()" + ] + }, + { + "cell_type": "code", + "execution_count": 121, + "id": "ce8ac22a", + "metadata": {}, + "outputs": [], + "source": [ + "#The dataframe as no duplicated." + ] + }, + { + "cell_type": "code", + "execution_count": 122, + "id": "ab266725", + "metadata": {}, + "outputs": [], + "source": [ + "# Resetting the index of the DataFrame\n", + "customer_data_insurance_clean_df = customer_data_insurance_clean_df.reset_index(drop=True)" + ] + }, + { + "cell_type": "markdown", + "id": "60840701-4783-40e2-b4d8-55303f9100c9", + "metadata": { + "id": "60840701-4783-40e2-b4d8-55303f9100c9" + }, + "source": [ + "# Bonus: Challenge 2: creating functions on a separate `py` file" + ] + }, + { + "cell_type": "markdown", + "id": "9d1adb3a-17cf-4899-8041-da21a4337fb4", + "metadata": { + "id": "9d1adb3a-17cf-4899-8041-da21a4337fb4" + }, + "source": [ + "Put all the data cleaning and formatting steps into functions, and create a main function that performs all the cleaning and formatting.\n", + "\n", + "Write these functions in separate .py file(s). By putting these steps into functions, we can make the code more modular and easier to maintain." + ] + }, + { + "cell_type": "markdown", + "id": "0e170dc2-b62c-417a-8248-e63ed18a70c4", + "metadata": { + "id": "0e170dc2-b62c-417a-8248-e63ed18a70c4" + }, + "source": [ + "*Hint: autoreload module is a utility module in Python that allows you to automatically reload modules in the current session when changes are made to the source code. This can be useful in situations where you are actively developing code and want to see the effects of changes you make without having to constantly restart the Python interpreter or Jupyter Notebook kernel.*" + ] + }, + { + "cell_type": "code", + "execution_count": 123, + "id": "65e61be9", + "metadata": {}, + "outputs": [], + "source": [ + "customer_data_insurance2_df =customer_data_insurance_df.copy()" + ] + }, + { + "cell_type": "code", + "execution_count": 124, + "id": "eaef878b", + "metadata": {}, + "outputs": [], + "source": [ + "def cle_for(df, state_conversion, gender_conversion):\n", + " # Standardizing names\n", + " df.columns = df.columns.str.lower().str.replace(\" \", \"_\")\n", + "\n", + " # Drop rows where all elements are NaN\n", + " df = df.dropna(axis=0, how=\"all\")\n", + " \n", + " # Map and replace categories\n", + " df[\"st\"] = df[\"st\"].map(state_conversion).fillna(df[\"st\"])\n", + " df[\"gender\"] = df[\"gender\"].map(gender_conversion).ffillna(df[\"gender\"])\n", + " \n", + " # Replace categories in education and vehicle_class\n", + " df['education'] = df['education'].replace({'Bachelors': 'Bachelor'})\n", + " df['vehicle_class'] = df['vehicle_class'].replace({\n", + " 'Sports Car': 'Luxury', 'Luxury SUV': 'Luxury', 'Luxury Car': 'Luxury'\n", + " })\n", + " \n", + " # Handle 'customer_lifetime_value'\n", + " df['customer_lifetime_value'] = df['customer_lifetime_value'].str.replace('%', '', regex=False)\n", + " df['customer_lifetime_value'] = pd.to_numeric(\n", + " df['customer_lifetime_value'], errors='coerce'\n", + " )\n", + " median_value = df['customer_lifetime_value'].median()\n", + " df['customer_lifetime_value'] = df['customer_lifetime_value'].fillna(median_value)\n", + " \n", + " # Handle 'number_of_open_complaints'\n", + " df['number_of_open_complaints'] = df['number_of_open_complaints'].apply(\n", + " lambda x: int(x.split('/')[1]) if pd.notnull(x) else x\n", + " ).astype(pd.Int64Dtype()) # This handles NaNs properly with Int64\n", + " \n", + " # Reset index\n", + " df = df.reset_index(drop=True)\n", + " \n", + " return df" + ] + }, + { + "cell_type": "code", + "execution_count": 125, + "id": "0c4e5b7c", + "metadata": {}, + "outputs": [], + "source": [ + "state_conversion = {\n", + " 'Cali': 'California', 'AZ': 'Arizona', 'WA': 'Washington',\n", + " 'Washington': 'Washington', 'Arizona': 'Arizona', 'Nevada': 'Nevada', 'California': 'California', 'Oregon': 'Oregon'\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": 126, + "id": "7ff6bd37", + "metadata": {}, + "outputs": [], + "source": [ + "gender_conversion = {\n", + " \"Male\": \"M\", \"Female\": \"F\", \"Femal\": \"F\"\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": 127, + "id": "91730d19", + "metadata": {}, + "outputs": [], + "source": [ + "%reload_ext autoreload\n", + "%autoreload 2\n", + "\n", + "from function import cle_for" + ] + }, + { + "cell_type": "code", + "execution_count": 128, + "id": "74ce76b5", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " customer st gender education \\\n", + "0 RB50392 Washington NaN Master \n", + "1 QZ44356 Arizona F Bachelor \n", + "2 AI49188 Nevada F Bachelor \n", + "3 WW63253 California M Bachelor \n", + "4 GA49547 Washington M High School or Below \n", + "... ... ... ... ... \n", + "1066 TM65736 Oregon M Master \n", + "1067 VJ51327 California F High School or Below \n", + "1068 GS98873 Arizona F Bachelor \n", + "1069 CW49887 California F Master \n", + "1070 MY31220 California F College \n", + "\n", + " customer_lifetime_value income monthly_premium_auto \\\n", + "0 588174.235 0.0 1000.0 \n", + "1 697953.590 0.0 94.0 \n", + "2 1288743.170 48767.0 108.0 \n", + "3 764586.180 0.0 106.0 \n", + "4 536307.650 36357.0 68.0 \n", + "... ... ... ... \n", + "1066 305955.030 38644.0 78.0 \n", + "1067 2031499.760 63209.0 102.0 \n", + "1068 323912.470 16061.0 88.0 \n", + "1069 462680.110 79487.0 114.0 \n", + "1070 899704.020 54230.0 112.0 \n", + "\n", + " number_of_open_complaints policy_type vehicle_class \\\n", + "0 0 Personal Auto Four-Door Car \n", + "1 0 Personal Auto Four-Door Car \n", + "2 0 Personal Auto Two-Door Car \n", + "3 0 Corporate Auto SUV \n", + "4 0 Personal Auto Four-Door Car \n", + "... ... ... ... \n", + "1066 1 Personal Auto Four-Door Car \n", + "1067 2 Personal Auto SUV \n", + "1068 0 Personal Auto Four-Door Car \n", + "1069 0 Special Auto SUV \n", + "1070 0 Personal Auto Two-Door Car \n", + "\n", + " total_claim_amount \n", + "0 2.704934 \n", + "1 1131.464935 \n", + "2 566.472247 \n", + "3 529.881344 \n", + "4 17.269323 \n", + "... ... \n", + "1066 361.455219 \n", + "1067 207.320041 \n", + "1068 633.600000 \n", + "1069 547.200000 \n", + "1070 537.600000 \n", + "\n", + "[1071 rows x 11 columns]\n" + ] + } + ], + "source": [ + "# Clean and format the DataFrame\n", + "cleaned_df = cle_for(customer_data_insurance2_df, state_conversion, gender_conversion)\n", + "cleaned_df = cleaned_df.reset_index(drop=True)\n", + "\n", + "# Display the result\n", + "print(cleaned_df)" + ] + }, + { + "cell_type": "markdown", + "id": "80f846bb-3f5e-4ca2-96c0-900728daca5a", + "metadata": { + "id": "80f846bb-3f5e-4ca2-96c0-900728daca5a", + "tags": [] + }, + "source": [ + "# Bonus: Challenge 3: Analyzing Clean and Formated Data" + ] + }, + { + "cell_type": "markdown", + "id": "9021630e-cc90-446c-b5bd-264d6c864207", + "metadata": { + "id": "9021630e-cc90-446c-b5bd-264d6c864207" + }, + "source": [ + "You have been tasked with analyzing the data to identify potential areas for improving customer retention and profitability. Your goal is to identify customers with a high policy claim amount and a low customer lifetime value.\n", + "\n", + "In the Pandas Lab, we only looked at high policy claim amounts because we couldn't look into low customer lifetime values. If we had tried to work with that column, we wouldn't have been able to because customer lifetime value wasn't clean and in its proper format. So after cleaning and formatting the data, let's get some more interesting insights!\n", + "\n", + "Instructions:\n", + "\n", + "- Review the statistics again for total claim amount and customer lifetime value to gain an understanding of the data.\n", + "- To identify potential areas for improving customer retention and profitability, we want to focus on customers with a high policy claim amount and a low customer lifetime value. Consider customers with a high policy claim amount to be those in the top 25% of the total claim amount, and clients with a low customer lifetime value to be those in the bottom 25% of the customer lifetime value. Create a pandas DataFrame object that contains information about customers with a policy claim amount greater than the 75th percentile and a customer lifetime value in the bottom 25th percentile.\n", + "- Use DataFrame methods to calculate summary statistics about the high policy claim amount and low customer lifetime value data. To do so, select both columns of the dataframe simultaneously and pass it to the `.describe()` method. This will give you descriptive statistics, such as mean, median, standard deviation, minimum and maximum values for both columns at the same time, allowing you to compare and analyze their characteristics." + ] + }, + { + "cell_type": "code", + "execution_count": 129, + "id": "211e82b5-461a-4d6f-8a23-4deccb84173c", + "metadata": { + "id": "211e82b5-461a-4d6f-8a23-4deccb84173c" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " total_claim_amount customer_lifetime_value\n", + "count 40.000000 40.000000\n", + "mean 723.776577 341577.910000\n", + "std 149.280606 56921.472027\n", + "min 537.600000 228759.690000\n", + "25% 633.378846 304220.875000\n", + "50% 685.284189 365995.370000\n", + "75% 799.200000 387364.700000\n", + "max 1185.988301 402381.440000\n" + ] + } + ], + "source": [ + "# Calculate the 75th percentile for total_claim_amount and 25th percentile for customer_lifetime_value\n", + "claim_75th_percentile = cleaned_df[\"total_claim_amount\"].quantile(0.75)\n", + "clv_25th_percentile = cleaned_df[\"customer_lifetime_value\"].quantile(0.25)\n", + "\n", + "# Filter for high claim amounts and low customer lifetime value\n", + "filtered_df = cleaned_df[\n", + " (cleaned_df[\"total_claim_amount\"] > claim_75th_percentile) &\n", + " (cleaned_df[\"customer_lifetime_value\"] < clv_25th_percentile)\n", + "]\n", + "\n", + "# Calculate and display summary statistics\n", + "summary_stats = filtered_df[[\"total_claim_amount\", \"customer_lifetime_value\"]].describe()\n", + "\n", + "print(summary_stats)" + ] + }, + { + "cell_type": "code", + "execution_count": 130, + "id": "5168bf49", + "metadata": {}, + "outputs": [], + "source": [ + "#Analysis\n", + "#Improving Profitability:\n", + "#Since these customers have high claims but lower lifetime values, efforts could be focused on converting these engagements into higher value-over-time by upselling or developing relevant service enhancements.\n", + "#Variability Management:\n", + "#Given the variability in both claim amounts and lifetime values, customized approaches targeting customers near the max end of claims and low end of lifetime values might provide growth, or conversely, scrutinize unsustainable customer relationships.\n", + "#Retention Focus:\n", + "#Identifying potential for loyalty programs or incentives to this customer subset can drive customer retention and extend lifetime value, particularly focusing on getting lower-value customers to contribute higher ongoing profit" + ] + } + ], + "metadata": { + "colab": { + "provenance": [] + }, + "kernelspec": { + "display_name": "base", + "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.13.9" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}