{ "cells": [ { "cell_type": "markdown", "id": "938d39ea", "metadata": {}, "source": [ "# Data Cleaning" ] }, { "cell_type": "markdown", "id": "410f524b", "metadata": {}, "source": [ "**Data cleaning** is one most crucial but time-intensive steps in the data science pipeline. In 2014, the New York Times published an [article](https://www.nytimes.com/2014/08/18/technology/for-big-data-scientists-hurdle-to-insights-is-janitor-work.html?_r=0) which estimated that: \n", "\n", "> Data scientists spend 80% of their time cleaning, preparing, and organizing data. \n", "\n", "With improvements in the way we collect data, this percentage of time is probably slightly lower now than when the article was first published. But, data cleaning is still a very important process that needs to be taken care of before proceeding to data analysis. \n", "\n", "<img width=\"40%\" src=\"https://practicalpython.s3.us-east-2.amazonaws.com/assets/data_cleaning_comic.png\"/>\n", "\n", "Without cleaning our data, the results that we generate from it could be misleading. With garbage data, your results will also be garbage regardless of how much time you spend creating your model and fine-tuning it. \n", "\n", "So, let's get start with the longest but also most important chapter of this book: **data cleaning** ๐งน๐๏ธ. " ] }, { "cell_type": "markdown", "id": "320e469f", "metadata": {}, "source": [ "## 1) Cleaning our column names" ] }, { "cell_type": "markdown", "id": "2d99bd26", "metadata": {}, "source": [ "When we first loaded in our NYC real estate dataset, one of the first things that I noticed was the column names. Let's take a look again:" ] }, { "cell_type": "code", "execution_count": 1, "id": "3ef88f17", "metadata": {}, "outputs": [ { "data": { "text/html": [ "<div>\n", "<style scoped>\n", " .dataframe tbody tr th:only-of-type {\n", " vertical-align: middle;\n", " }\n", "\n", " .dataframe tbody tr th {\n", " vertical-align: top;\n", " }\n", "\n", " .dataframe thead th {\n", " text-align: right;\n", " }\n", "</style>\n", "<table border=\"1\" class=\"dataframe\">\n", " <thead>\n", " <tr style=\"text-align: right;\">\n", " <th></th>\n", " <th>BOROUGH</th>\n", " <th>NEIGHBORHOOD</th>\n", " <th>BUILDING CLASS CATEGORY</th>\n", " <th>TAX CLASS AT PRESENT</th>\n", " <th>BLOCK</th>\n", " <th>LOT</th>\n", " <th>EASE-MENT</th>\n", " <th>BUILDING CLASS AT PRESENT</th>\n", " <th>ADDRESS</th>\n", " <th>APARTMENT NUMBER</th>\n", " <th>...</th>\n", " <th>RESIDENTIAL UNITS</th>\n", " <th>COMMERCIAL UNITS</th>\n", " <th>TOTAL UNITS</th>\n", " <th>LAND SQUARE FEET</th>\n", " <th>GROSS SQUARE FEET</th>\n", " <th>YEAR BUILT</th>\n", " <th>TAX CLASS AT TIME OF SALE</th>\n", " <th>BUILDING CLASS AT TIME OF SALE</th>\n", " <th>SALE PRICE</th>\n", " <th>SALE DATE</th>\n", " </tr>\n", " </thead>\n", " <tbody>\n", " <tr>\n", " <th>37371</th>\n", " <td>3</td>\n", " <td>FLATBUSH-CENTRAL</td>\n", " <td>02 TWO FAMILY DWELLINGS</td>\n", " <td>1</td>\n", " <td>5229</td>\n", " <td>74</td>\n", " <td></td>\n", " <td>B1</td>\n", " <td>1295 ROGERS AVENUE</td>\n", " <td></td>\n", " <td>...</td>\n", " <td>2</td>\n", " <td>0</td>\n", " <td>2</td>\n", " <td>4429</td>\n", " <td>1523</td>\n", " <td>1899</td>\n", " <td>1</td>\n", " <td>B1</td>\n", " <td>0</td>\n", " <td>2017-01-05 00:00:00</td>\n", " </tr>\n", " </tbody>\n", "</table>\n", "<p>1 rows ร 21 columns</p>\n", "</div>" ], "text/plain": [ " BOROUGH NEIGHBORHOOD BUILDING CLASS CATEGORY \\\n", "37371 3 FLATBUSH-CENTRAL 02 TWO FAMILY DWELLINGS \n", "\n", " TAX CLASS AT PRESENT BLOCK LOT EASE-MENT BUILDING CLASS AT PRESENT \\\n", "37371 1 5229 74 B1 \n", "\n", " ADDRESS APARTMENT NUMBER ... RESIDENTIAL UNITS \\\n", "37371 1295 ROGERS AVENUE ... 2 \n", "\n", " COMMERCIAL UNITS TOTAL UNITS LAND SQUARE FEET GROSS SQUARE FEET \\\n", "37371 0 2 4429 1523 \n", "\n", " YEAR BUILT TAX CLASS AT TIME OF SALE BUILDING CLASS AT TIME OF SALE \\\n", "37371 1899 1 B1 \n", "\n", " SALE PRICE SALE DATE \n", "37371 0 2017-01-05 00:00:00 \n", "\n", "[1 rows x 21 columns]" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import pandas as pd \n", "\n", "df = pd.read_csv(\"data/nyc_real_estate.csv\")\n", "df.sample()" ] }, { "cell_type": "markdown", "id": "f53780af", "metadata": {}, "source": [ "The column names are all uppercase and have spaces between words. This is not an ideal format for our analysis because we'll be calling these column names often and it's annoying to worry about capitlization and spacing. My ideal format for column names are:\n", "\n", "1. lowercase \n", "2. [snakecase](https://en.wikipedia.org/wiki/Snake_case) (when spaces are replaced with `_` underscores)\n", "\n", "Let's look at one of the columns from our dataset as an example. The column name is current formatted like this:\n", "\n", "**`BUILDING CLASS CATEGORY`** ๐คฎ \n", "\n", "The ideal format would look something like this: \n", "\n", "**`building_class_category`** ๐\n", "\n", "In order to make this change, we can write a function that does this transformation for us. Let's start with our example of BUILDING CLASS CATEGORY." ] }, { "cell_type": "code", "execution_count": 2, "id": "58d91e06", "metadata": {}, "outputs": [], "source": [ "original = 'BUILDING CLASS CATEGORY'" ] }, { "cell_type": "markdown", "id": "628d6048", "metadata": {}, "source": [ "The first thing we want to do is make the name all lowercase. We can use Python built-in [`lower()`](https://www.programiz.com/python-programming/methods/string/lower) function to do this:" ] }, { "cell_type": "code", "execution_count": 3, "id": "bf999c3b", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'building class category'" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "original.lower()" ] }, { "cell_type": "markdown", "id": "33c1deae", "metadata": {}, "source": [ "Great! The next thing we need to do is replace spaces with underscores:" ] }, { "cell_type": "code", "execution_count": 4, "id": "93936307", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'building_class_category'" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "original.lower().replace(' ', '_')" ] }, { "cell_type": "markdown", "id": "6b5788a7", "metadata": {}, "source": [ "We can now create a function out of this:" ] }, { "cell_type": "code", "execution_count": 5, "id": "79c0abac", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'building_class_category'" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def clean_column_name(column):\n", " return column.lower().replace(' ', '_')\n", "\n", "clean_column_name(original)" ] }, { "cell_type": "markdown", "id": "3eec6afb", "metadata": {}, "source": [ "To apply this to ALL columns, we'll need to loop over each column name and apply our `clean_column_name()` function to it. Let's create a dictionary, `column_dict`, that maps our original column name to our new column name: \n", "\n", "\n", "```\n", "{ original_column_name : new_column_name }\n", "```" ] }, { "cell_type": "code", "execution_count": 6, "id": "d4c551aa", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'BOROUGH': 'borough',\n", " 'NEIGHBORHOOD': 'neighborhood',\n", " 'BUILDING CLASS CATEGORY': 'building_class_category',\n", " 'TAX CLASS AT PRESENT': 'tax_class_at_present',\n", " 'BLOCK': 'block',\n", " 'LOT': 'lot',\n", " 'EASE-MENT': 'ease-ment',\n", " 'BUILDING CLASS AT PRESENT': 'building_class_at_present',\n", " 'ADDRESS': 'address',\n", " 'APARTMENT NUMBER': 'apartment_number',\n", " 'ZIP CODE': 'zip_code',\n", " 'RESIDENTIAL UNITS': 'residential_units',\n", " 'COMMERCIAL UNITS': 'commercial_units',\n", " 'TOTAL UNITS': 'total_units',\n", " 'LAND SQUARE FEET': 'land_square_feet',\n", " 'GROSS SQUARE FEET': 'gross_square_feet',\n", " 'YEAR BUILT': 'year_built',\n", " 'TAX CLASS AT TIME OF SALE': 'tax_class_at_time_of_sale',\n", " 'BUILDING CLASS AT TIME OF SALE': 'building_class_at_time_of_sale',\n", " 'SALE PRICE': 'sale_price',\n", " 'SALE DATE': 'sale_date'}" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "column_dict = dict()\n", "\n", "for c in df.columns:\n", " column_dict[c] = clean_column_name(c)\n", "\n", "column_dict" ] }, { "cell_type": "markdown", "id": "0c94ab13", "metadata": {}, "source": [ "Great! We can now overwrite original column names with the new column names using pandas' [`rename()`](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.rename.html) function. " ] }, { "cell_type": "code", "execution_count": 7, "id": "8eb90292", "metadata": {}, "outputs": [ { "data": { "text/html": [ "<div>\n", "<style scoped>\n", " .dataframe tbody tr th:only-of-type {\n", " vertical-align: middle;\n", " }\n", "\n", " .dataframe tbody tr th {\n", " vertical-align: top;\n", " }\n", "\n", " .dataframe thead th {\n", " text-align: right;\n", " }\n", "</style>\n", "<table border=\"1\" class=\"dataframe\">\n", " <thead>\n", " <tr style=\"text-align: right;\">\n", " <th></th>\n", " <th>borough</th>\n", " <th>neighborhood</th>\n", " <th>building_class_category</th>\n", " <th>tax_class_at_present</th>\n", " <th>block</th>\n", " <th>lot</th>\n", " <th>ease-ment</th>\n", " <th>building_class_at_present</th>\n", " <th>address</th>\n", " <th>apartment_number</th>\n", " <th>...</th>\n", " <th>residential_units</th>\n", " <th>commercial_units</th>\n", " <th>total_units</th>\n", " <th>land_square_feet</th>\n", " <th>gross_square_feet</th>\n", " <th>year_built</th>\n", " <th>tax_class_at_time_of_sale</th>\n", " <th>building_class_at_time_of_sale</th>\n", " <th>sale_price</th>\n", " <th>sale_date</th>\n", " </tr>\n", " </thead>\n", " <tbody>\n", " <tr>\n", " <th>47339</th>\n", " <td>3</td>\n", " <td>SUNSET PARK</td>\n", " <td>09 COOPS - WALKUP APARTMENTS</td>\n", " <td>2</td>\n", " <td>750</td>\n", " <td>5</td>\n", " <td></td>\n", " <td>C6</td>\n", " <td>712 45TH STREET, 2D</td>\n", " <td></td>\n", " <td>...</td>\n", " <td>0</td>\n", " <td>0</td>\n", " <td>0</td>\n", " <td>0</td>\n", " <td>0</td>\n", " <td>1924</td>\n", " <td>2</td>\n", " <td>C6</td>\n", " <td>395000</td>\n", " <td>2016-09-27 00:00:00</td>\n", " </tr>\n", " </tbody>\n", "</table>\n", "<p>1 rows ร 21 columns</p>\n", "</div>" ], "text/plain": [ " borough neighborhood building_class_category \\\n", "47339 3 SUNSET PARK 09 COOPS - WALKUP APARTMENTS \n", "\n", " tax_class_at_present block lot ease-ment building_class_at_present \\\n", "47339 2 750 5 C6 \n", "\n", " address apartment_number ... residential_units \\\n", "47339 712 45TH STREET, 2D ... 0 \n", "\n", " commercial_units total_units land_square_feet gross_square_feet \\\n", "47339 0 0 0 0 \n", "\n", " year_built tax_class_at_time_of_sale building_class_at_time_of_sale \\\n", "47339 1924 2 C6 \n", "\n", " sale_price sale_date \n", "47339 395000 2016-09-27 00:00:00 \n", "\n", "[1 rows x 21 columns]" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df = df.rename(columns=column_dict)\n", "df.sample()" ] }, { "cell_type": "markdown", "id": "f3aef945", "metadata": {}, "source": [ "Columns look great now! ๐\n", "\n", "<img width=\"40%\" src=\"https://media.giphy.com/media/3otPom0tSP4zgfrakE/giphy.gif\"/>" ] }, { "cell_type": "markdown", "id": "0eba8ca6", "metadata": {}, "source": [ "## 2) Dropping columns \n", "\n", "Our dataset has 21 columns but we won't be using all of them for our analysis. For example, for this specific exploration, we don't care so much about the following columns: \n", "\n", "- ease-ment \n", "- lot \n", "- block \n", "- tax_class_at_time_of_sale\n", "- tax_class_at_present\n", "\n", "We can remove these columns from our dataframe using the [`.drop()`](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.drop.html) function. With `.drop()`, you can choose to drop columns by specifying its index (numeric location in the datafarme) or column name. It's often easier to explicitly remove specific columns by name so let's do that. First, we need to create a list of the columns we want to remove: " ] }, { "cell_type": "code", "execution_count": 8, "id": "2efae3e9", "metadata": {}, "outputs": [], "source": [ "columns_to_remove = ['ease-ment', 'lot', 'block', 'tax_class_at_present', 'tax_class_at_time_of_sale']" ] }, { "cell_type": "markdown", "id": "0e502bd4", "metadata": {}, "source": [ "Now, we can drop these columns using the `.drop()` function:" ] }, { "cell_type": "code", "execution_count": 9, "id": "1146e462", "metadata": {}, "outputs": [], "source": [ "df = df.drop(columns=columns_to_remove)" ] }, { "cell_type": "markdown", "id": "36c62b8a", "metadata": {}, "source": [ "```{important}\n", "We're overwritting our dataframe with a new version that removes the 5 columns we don't need. If we try re-running this code, after having removed the columns, we'll get an error message that says: \n", "> KeyError: \"['ease-ment' 'lot' 'block' 'tax_class_at_present'\\n 'tax_class_at_time_of_sale'] not found in axis\"\n", "Make sure that you only drop a column once. Trying to drop a column that doesn't exist in yoru dataframe will cause your code to break. \n", "```" ] }, { "cell_type": "markdown", "id": "e89f871a", "metadata": {}, "source": [ "Let's see how many columns are in our dataset now:" ] }, { "cell_type": "code", "execution_count": 10, "id": "28c6ea32", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(84548, 16)" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.shape" ] }, { "cell_type": "markdown", "id": "0f2ca048", "metadata": {}, "source": [ "Awesome! Our dataframe went from 21 columns to 16 columns, which makes sense because we just removed 5 columns that we don't need." ] }, { "cell_type": "markdown", "id": "a632c65f", "metadata": {}, "source": [ "## 3) Fixing column datatypes" ] }, { "cell_type": "markdown", "id": "0c13c097", "metadata": {}, "source": [ "When we first load in a dataframe, it's very possible that column datatypes don't get loaded in correctly. For example, numerical columns get loaded in as \"object\" datatypes instead of integer/float. Datetime columns also get loaded in as a string (object) datatype by default so it's our responsibility to cast our column datatypes into their appropriate formats.\n", "\n", "Before we start fixing our datatype, let's quickly review what the possible datatypes are. You can also check out the pandas [datatype documentation](https://pandas.pydata.org/pandas-docs/stable/user_guide/basics.html#basics-dtypes) for more information. \n", "- `int64`: Whole number integer datatypes\n", "- `float64`: Floating number (fractional number, with decimal) datatypes\n", "- `bool`: True or False boolean datatypes \n", "- `object`: A \"catch-all\" datatype that usually represents a string datatype or contains a mix of more than one datatype (e.g., string + integer)\n", "\n", "\n", "Let's get a glimpse of our dataframe's datatypes:" ] }, { "cell_type": "code", "execution_count": 11, "id": "5c332b90", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "borough int64\n", "neighborhood object\n", "building_class_category object\n", "building_class_at_present object\n", "address object\n", "apartment_number object\n", "zip_code int64\n", "residential_units int64\n", "commercial_units int64\n", "total_units int64\n", "land_square_feet object\n", "gross_square_feet object\n", "year_built int64\n", "building_class_at_time_of_sale object\n", "sale_price object\n", "sale_date object\n", "dtype: object" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.dtypes" ] }, { "cell_type": "markdown", "id": "5e69d842", "metadata": {}, "source": [ "There are several columns that are listed as \"object\" that I think could be integers or floats instead:\n", "\n", "- `land_square_feet`\n", "- `gross_square_feet`\n", "- `sale_price`\n", "\n", "To convert an object column into a float column, we can try the brute-force approach of `astype()`:\n", "\n", "```\n", "df['sale_price'].astype(float)\n", "```\n", "\n", "If you try this, you'll see that an error gets thrown:\n", "\n", "```\n", "ValueError: could not convert string to float: ' - '\n", "```\n", "\n", "This indicates that there are some values in this `sale_price` column that cannot be convert to float. We'll have to handle these first before proceeding. Let's use the Pandas Series `.replace()` function to replace `' - '` with `None` (to indicate a missing value).\n", "\n", "โ**String vs. Pandas `replace()` function**\n", "\n", "The string `replace()` function looks like this:\n", "\n", "```\n", "replace(current_value, new_value)\n", "```\n", "\n", "The syntax for Pandas `.replace()` is a bit different since it uses a dictionary instead:\n", "\n", "```\n", "replace({current_value: new_value})\n", "```\n", "\n", "Let's try it out on our dataset:" ] }, { "cell_type": "code", "execution_count": 12, "id": "72d7b4d9", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "dtype('float64')" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df['sale_price'] = df['sale_price'].replace({' - ': None})\n", "df['sale_price'] = df['sale_price'].astype(float)\n", "df['sale_price'].dtype" ] }, { "cell_type": "markdown", "id": "365fe7dd", "metadata": {}, "source": [ "After removing that weird hyphen string from our `sale_price` column, we were able to successfully cast our column to a float datatype. ๐ฅณ\n", "\n", "We can apply the same approach to the `land_square_feet` and `gross_square_feet` columns." ] }, { "cell_type": "code", "execution_count": 13, "id": "fbb093bd", "metadata": {}, "outputs": [], "source": [ "df['land_square_feet'] = df['land_square_feet'].replace({' - ': None}).astype(float)\n", "df['gross_square_feet'] = df['gross_square_feet'].replace({' - ': None}).astype(float)" ] }, { "cell_type": "markdown", "id": "0e6497c5", "metadata": {}, "source": [ "Now, the last column that we should fix is the `sale_date` column. It's default datatype is \"object\" but we can convert this to a datetime datatype using pandas' [`to_datetime()`](https://pandas.pydata.org/docs/reference/api/pandas.to_datetime.html) function" ] }, { "cell_type": "code", "execution_count": 14, "id": "576c2cf6", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "dtype('<M8[ns]')" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df['sale_date'] = pd.to_datetime(df['sale_date'])\n", "df['sale_date'].dtype" ] }, { "cell_type": "markdown", "id": "3390ab8f", "metadata": {}, "source": [ "After applying `to_datetime()`, we can see that the `sale_date` column's datatype is now `'<M8[ns]'` which is a datetime datatype. " ] }, { "cell_type": "markdown", "id": "7408ff38", "metadata": {}, "source": [ "## 4) Handling Missing Values\n", "\n", "Remember in Chapter 2 when we thought that our data didn't have any missing values? This is no longer the case after cleaning our data. We know that the following columns have missing values:\n", "\n", "- sale_price\n", "- land_square_feet\n", "- gross_square_feet\n", "\n", "Let's re-assess how many missing values we're dealing with.\n", "\n", "<img src=\"https://media.giphy.com/media/NS7gPxeumewkWDOIxi/giphy.gif\"/>" ] }, { "cell_type": "markdown", "id": "c8398cfc", "metadata": {}, "source": [ "How many missing values are we dealing with for each column in our dataframe?" ] }, { "cell_type": "code", "execution_count": 15, "id": "f601a5f2", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "borough 0\n", "neighborhood 0\n", "building_class_category 0\n", "building_class_at_present 0\n", "address 0\n", "apartment_number 0\n", "zip_code 0\n", "residential_units 0\n", "commercial_units 0\n", "total_units 0\n", "land_square_feet 26252\n", "gross_square_feet 27612\n", "year_built 0\n", "building_class_at_time_of_sale 0\n", "sale_price 14561\n", "sale_date 0\n", "dtype: int64" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.isnull().sum()" ] }, { "cell_type": "markdown", "id": "968b37e7", "metadata": {}, "source": [ "Wow! We can see that there are more missing values for the square footage columns as comopared to the sale price column. Let's check out what percentage of values are missing for each column. We can do this by simply dividing the missing value count for each column by the total number of rows in our dataframe:" ] }, { "cell_type": "code", "execution_count": 16, "id": "ee34b781", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "borough 0.000000\n", "neighborhood 0.000000\n", "building_class_category 0.000000\n", "building_class_at_present 0.000000\n", "address 0.000000\n", "apartment_number 0.000000\n", "zip_code 0.000000\n", "residential_units 0.000000\n", "commercial_units 0.000000\n", "total_units 0.000000\n", "land_square_feet 0.310498\n", "gross_square_feet 0.326584\n", "year_built 0.000000\n", "building_class_at_time_of_sale 0.000000\n", "sale_price 0.172222\n", "sale_date 0.000000\n", "dtype: float64" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.isnull().sum() / len(df)" ] }, { "cell_type": "markdown", "id": "33fb1d0c", "metadata": {}, "source": [ "Over 30% of properties don't have square footage data, while 17% of properties don't have sale price. \n", "\n", "An interesting thing to know is which rows have missing values. Ideally, the missing values are occuring in the same properties:" ] }, { "cell_type": "code", "execution_count": 17, "id": "cd3aeafb", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "<AxesSubplot:>" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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OdRCqc9//vO3zpRfj/RkBwAAAACgM6eddlrXJayIkB0AAAAAgM689a1v7bqEFdEuBgAAAACA7Zqfn++6hDVLyA4AAADAqrHwaTsWPmWtm52dHdl9n3vuubnd7W43svsfNSE7AADAmPR6vczNzXVdxrqyuBigcRuehRTpioVPh+f5yqQ77rjj1vVMeSE7AADAmExPT5vh2ZJxa8fMWAAYPSE7AAAAAADbde973zullGW3JJmamkopJR/72MeGvu/zzjtvlasdLyE7AAAAAADb9ZKXvGSn9jv11FNHXMnaI2QHAAAAAGC7Rrnw6V/8xV/kTne608juf9SE7AAAAGNi4dPhWfi0PQspArBeHH/88RY+BQAAYMcsfNqecWvHwqcAMHpCdgAAgDExk314i7Oxp6enO60D2HkOirXjoBisX0J2AACAMTGTHQBg4xGyAwAAALBqZmZmui5h3bGGAqxvU10XAAAAAADA5HrYwx7WdQkrYiY7AAAAAACr5thjj82BBx6YUsrWy0opW7fBy/bff//c5z736aLMVSNkBwAAAABg1bznPe8Zav9DDz00b3vb20ZUzehpFwMAAAAAQGce97jHdV3CipjJDgAAAMCqWVhY6LqEdanX63VdAnTmnHPOyYMf/OCuy2hNyA4AAADAqpmZmem6hHVn8+bNXZcAnZqenu66hBURsgMAAAAAsF2HHnpokmxduLTWmlrr1u8X3eQmN8nRRx+9zQKngwZvU2vNvvvum/ve976jLH3khOwAAAAAAGzXN77xjZ3e90tf+tLQ9z8/Pz/0bdYKC58CAAAAANCZE088sesSVkTIDgAAAABAZ+5617t2XcKKCNkBAAAAAOjMj370o65LWBE92QEAAAAA2K713DN91ITsAAAAAKyahYWFrktYl3q9XtclAC0J2QEAAABYNTMzM12XsO5s3ry56xKAFRCyAwAAAACwXbOzsyO535vf/OY599xzs88++4zk/sdByA4AAADAqtEuph3tYphU3/nOd3LmmWfmxS9+cdeltCZkBwAAAGDVaBczPO1imHR3uMMdui5hRaa6LgAAAAAAgMl18MEHd13CipjJDgAAAADAds3Pz3ddwpplJjsAAAAAALRkJjsAAAAAANs1Ozu70/sed9xxOeSQQ1JK2eG2yy675Igjjsjuu+8+wupHS8gOAAAAAMCqOffcc4fa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AEBLQnYAAAAAAGhJyA4AAAAAAC0J2QEAAAAAoCUhOwAAAAAAtCRkBwAAAACAloTsAAAAAADQkpAdAAAAAABaErIDAAAAAEBLQnYAAAAAAGhJyA4AAAAAAC0J2QEAAAAAoCUhOwAAAAAAtCRkBwAAAACAloTsAAAAAADQkpAdAAAAAABaErIDAAAAAEBLQnYAAAAAAGhJyA4AAAAAAC0J2QEAAAAAoCUhOwAAAAAAtCRkBwAAAACAloTsAAAAAADQkpAdAAAAAABaErIDAAAAAEBLQnYAAAAAAGhJyA4AAAAAAC0J2QEAAAAAoCUhOwAAAAAAtCRkBwAAAACAloTsAAAAAADQkpAdAAAAAABaErIDAAAAAEBLQnYAAAAAAGhJyA4AAAAAAC0J2QEAAAAAoCUhOwAAAAAAtCRkBwAAAACAloTsAAAAAADQkpAdAAAAAABaErIDAAAAAEBLQnYAAAAAAGhJyA4AAAAAAC0J2QEAAAAAoCUhOwAAAAAAtCRkBwAAAACAloTsAAAAAADQkpAdAAAAAABaErIDAAAAAEBLQnYAAAAAAGhJyA4AAAAAAC0J2QEAAAAAoCUhOwAAAAAAtCRkBwAAAACAloTsAAAAAADQkpAdAAAAAABaErIDAAAAAEBLQnYAAAAAAGhJyA4AAAAAAC0J2QEAAAAAoCUhOwAAAAAAtCRkBwAAAACAloTsAAAAAADQkpAdAAAAAABaErIDAAAAAEBLQnYAAAAAAGhJyA4AAAAAAC0J2QEAAAAAoCUhOwAAAAAAtCRkBwAAAACAloTsAAAAAADQkpAdAAAAAABaErIDAAAAAEBLQnYAAAAAAGhJyA4AAAAAAC0J2QEAAAAAoCUhOwAAAAAAtCRkBwAAAACAloTsAAAAAADQkpAdAAAAAABaErIDAAAAAEBLQnYAAAAAAGhJyA4AAAAAAC0J2QEAAAAAoCUhOwAAAAAAtCRkBwAAAACAloTsAAAAAADQkpAdAAAAAABaErIDAAAAAEBLQnYAAAAAAGhJyA4AAAAAAC0J2QEAAAAAoCUhOwAAAAAAtCRkBwAAAACAloTsAAAAAADQkpAdAAAAAABaErIDAAAAAEBLQnYAAAAAAGhJyA4AAAAAAC0J2QEAAAAAoCUhOwAAAAAAtCRkBwAAAACAloTsAAAAAADQkpAdAAAAAABaErIDAAAAAEBL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\n", "text/plain": [ "<Figure size 1800x720 with 2 Axes>" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "import missingno as msno\n", "\n", "msno.matrix(df)" ] }, { "cell_type": "markdown", "id": "1b6bc8e6", "metadata": {}, "source": [ "The missing value matrix shows that missing values across the 3 columns are indeed correlated as they apear to affect the same properties. " ] }, { "cell_type": "code", "execution_count": 18, "id": "03507f44", "metadata": {}, "outputs": [], "source": [ "df = df.dropna(subset=['sale_price'])" ] }, { "cell_type": "markdown", "id": "255ee33f", "metadata": {}, "source": [ "## 5) Subsetting the data\n", "\n", "Now that we have properly formatted column names and our columns are represented in their appropriate datatypes, we can start to explore our data and check to see if the data values make sense. If the data *doesn't* make sense, we can subset our dataframe to only include data that fits within a reasonable range. This process is called **subsetting** the data. \n", "\n", "It's definitely more of an art than a science, and requires having some context about your data in order to evaluate what makes sense. Let's give this a try with our dataframe. \n", "\n", "We'll focus on the column `year_built` column and see if the numbers make sense. According to [this source](https://ny.curbed.com/maps/nyc-oldest-buildings-houses-map), the oldest building in New York City was built around the 1650s so any building that was built before this time is probably not accurate. \n", "\n", "What's the minimum `year_built` in our dataset?" ] }, { "cell_type": "code", "execution_count": 19, "id": "d8c477ee", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df['year_built'].min()" ] }, { "cell_type": "markdown", "id": "22a6acde", "metadata": {}, "source": [ "\"0\" years?! This does not make any sense. Let's drop this from our dataset. In order to do this, we need to create a subset of our dataframe that only includes rows that have `year_built` over 1650. \n", "\n", "We can leverage the boolean comparison operator to do this. " ] }, { "cell_type": "code", "execution_count": 20, "id": "1e37c551", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 True\n", "3 True\n", "4 True\n", "6 True\n", "9 True\n", " ... \n", "84543 True\n", "84544 True\n", "84545 True\n", "84546 True\n", "84547 True\n", "Name: year_built, Length: 69987, dtype: bool" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df['year_built'] > 1650" ] }, { "cell_type": "markdown", "id": "77fa25b1", "metadata": {}, "source": [ "The boolean logic above asks the question: \n", "\n", "> Is this property's `year_built` above 1650? \n", "\n", "If the answer is yes, it returns \"True\". If no, then it returns \"False\". If we wrap this logic into our dataframe, we'll end up with a subset of our original dataframe that only keeps the rows where the boolean condition is True \n", "(`year_built` is greater than 1650).\n", "\n", "<img width=\"60%\" src=\"https://practicalpython.s3.us-east-2.amazonaws.com/assets/boolean_logic.png\"/>\n", "\n", "Let's create the subset of our dataframe and assign it a new variable name, `df_filtered`." ] }, { "cell_type": "code", "execution_count": 21, "id": "7d8de34c", "metadata": {}, "outputs": [], "source": [ "df_filtered = df[df['year_built'] > 1650]" ] }, { "cell_type": "markdown", "id": "f6a7b266", "metadata": {}, "source": [ "How many rows do we have now? We can use the `len()` function to the count number of rows. \n", "\n", "> Alternatively, we could also use `df.shape`, which returns `(n_rows, n_columns)` and take the first element of the tuple." ] }, { "cell_type": "code", "execution_count": 22, "id": "df3aad43", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "64595" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "len(df_filtered)" ] }, { "cell_type": "markdown", "id": "dfa53147", "metadata": {}, "source": [ "How many rows did we remove? We can find out by subscracting the number of rows of our original dataframe from the rows of our filtered dataframe. " ] }, { "cell_type": "code", "execution_count": 23, "id": "aa1c3e62", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "We removed 5392 rows!\n" ] } ], "source": [ "print(f\"We removed {len(df) - len(df_filtered)} rows!\")" ] }, { "cell_type": "markdown", "id": "e008d75a", "metadata": {}, "source": [ "Wow! We removed almost 7K rows - that is a pretty significant number of properties that had `year_built` below 1650.\n", "\n", "Let's take a look at the new lower `year_built` value in our filtered dataframe." ] }, { "cell_type": "code", "execution_count": 24, "id": "e2e3dc5a", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1800" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_filtered['year_built'].min()" ] }, { "cell_type": "markdown", "id": "cce7ce9b", "metadata": {}, "source": [ "This minimum value makes much more sense. \n", "\n", "<img src=\"https://media.giphy.com/media/IwAZ6dvvvaTtdI8SD5/giphy.gif\"/>" ] }, { "cell_type": "markdown", "id": "05872b5d", "metadata": {}, "source": [ "## 6) Recoding column values" ] }, { "cell_type": "markdown", "id": "c91ca6f7", "metadata": {}, "source": [ "Since we're dealing with New York City properties, it's important to make sure we have a column that represents which borough the property is located in. This `borough` column will be very important for our analysis because property value can vary greatly based on the borough that it's in. For example, we would expect the median price of a property is very different in Manhattan as compared to Staten Island. " ] }, { "cell_type": "code", "execution_count": 25, "id": "a4eb2176", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([1, 2, 3, 4, 5])" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_filtered['borough'].unique()" ] }, { "cell_type": "markdown", "id": "63500a9a", "metadata": {}, "source": [ "The Kaggle description explains how the borough column is encoded:\n", "\n", "> A digit code for the borough the property is located in; in order these are Manhattan (1), Bronx (2), Brooklyn (3), Queens (4), and Staten Island (5).\n", "\n", "Let's recode the borough column into human-readable names instead of using the coded numbers. We can do this using pandas' [`replace()`](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.replace.html) function. The first thing we need to do is create a dictionary that maps our numerical values to the appropriate borough names." ] }, { "cell_type": "code", "execution_count": 26, "id": "544a21f4", "metadata": {}, "outputs": [], "source": [ "boroughs_dict = {\n", " 1: 'Manhattan',\n", " 2: 'Bronx',\n", " 3: 'Brooklyn',\n", " 4: 'Queens',\n", " 5: 'Staten Island'\n", "}" ] }, { "cell_type": "markdown", "id": "471a2b7a", "metadata": {}, "source": [ "We can now apply `replace()` to our dataframe and pass the `boroughs_dict` inside of it." ] }, { "cell_type": "code", "execution_count": 27, "id": "6bf87788", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/var/folders/c6/66vf07tn12b7f11fct15gggm0000gn/T/ipykernel_91911/1217914364.py:1: SettingWithCopyWarning: \n", "A value is trying to be set on a copy of a slice from a DataFrame.\n", "Try using .loc[row_indexer,col_indexer] = value instead\n", "\n", "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n", " df_filtered['borough'] = df_filtered['borough'].replace(boroughs_dict)\n" ] } ], "source": [ "df_filtered['borough'] = df_filtered['borough'].replace(boroughs_dict)" ] }, { "cell_type": "markdown", "id": "53c9ef61", "metadata": {}, "source": [ "How do the new borough values look?" ] }, { "cell_type": "code", "execution_count": 28, "id": "72b099cd", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array(['Manhattan', 'Bronx', 'Brooklyn', 'Queens', 'Staten Island'],\n", " dtype=object)" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_filtered['borough'].unique()" ] }, { "cell_type": "markdown", "id": "b4f83056", "metadata": {}, "source": [ "Awesome! We've successfully recoded our borough column into human-readable values." ] }, { "cell_type": "markdown", "id": "e21b5f9f", "metadata": {}, "source": [ "## 7) Formatting column values\n", "\n", "While not absolutely necessary, it's nice to clean up and re-format the values of string columns. These small adjustments can make it easier to interpret our results when we analyze our data. In this section, we will clean up 2 columns: \n", "\n", "- `neighborhood`\n", "- `building_class_category`\n", "\n", "Let's see how they look:" ] }, { "cell_type": "code", "execution_count": 29, "id": "13aa39f3", "metadata": {}, "outputs": [ { "data": { "text/html": [ "<div>\n", "<style scoped>\n", " .dataframe tbody tr th:only-of-type {\n", " vertical-align: middle;\n", " }\n", "\n", " .dataframe tbody tr th {\n", " vertical-align: top;\n", " }\n", "\n", " .dataframe thead th {\n", " text-align: right;\n", " }\n", "</style>\n", "<table border=\"1\" class=\"dataframe\">\n", " <thead>\n", " <tr style=\"text-align: right;\">\n", " <th></th>\n", " <th>neighborhood</th>\n", " <th>building_class_category</th>\n", " </tr>\n", " </thead>\n", " <tbody>\n", " <tr>\n", " <th>59754</th>\n", " <td>FLUSHING-SOUTH</td>\n", " <td>09 COOPS - WALKUP APARTMENTS</td>\n", " </tr>\n", " <tr>\n", " <th>6366</th>\n", " <td>KIPS BAY</td>\n", " <td>10 COOPS - ELEVATOR APARTMENTS</td>\n", " </tr>\n", " <tr>\n", " <th>67687</th>\n", " <td>OAKLAND GARDENS</td>\n", " <td>01 ONE FAMILY DWELLINGS</td>\n", " </tr>\n", " <tr>\n", " <th>46546</th>\n", " <td>SHEEPSHEAD BAY</td>\n", " <td>12 CONDOS - WALKUP APARTMENTS</td>\n", " </tr>\n", " <tr>\n", " <th>21794</th>\n", " <td>MOUNT HOPE/MOUNT EDEN</td>\n", " <td>01 ONE FAMILY DWELLINGS</td>\n", " </tr>\n", " </tbody>\n", "</table>\n", "</div>" ], "text/plain": [ " neighborhood building_class_category\n", "59754 FLUSHING-SOUTH 09 COOPS - WALKUP APARTMENTS \n", "6366 KIPS BAY 10 COOPS - ELEVATOR APARTMENTS \n", "67687 OAKLAND GARDENS 01 ONE FAMILY DWELLINGS \n", "46546 SHEEPSHEAD BAY 12 CONDOS - WALKUP APARTMENTS \n", "21794 MOUNT HOPE/MOUNT EDEN 01 ONE FAMILY DWELLINGS " ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_filtered[['neighborhood', 'building_class_category']].sample(5)" ] }, { "cell_type": "markdown", "id": "fbbbdfbd", "metadata": {}, "source": [ "### Neighborhood\n", "\n", "The `neighborhood` column is currently all uppercase. We want to modify it so that the first letter of each word is uppercase and the rest is lowercase. To do this, there are 2 options we can consider: \n", "\n", "1. `title()`\n", "2. `capitalize()` " ] }, { "cell_type": "code", "execution_count": 30, "id": "3fd98895", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "neighborhood.title() : Alphabet City\n", "neighborhood.capitalize() : Alphabet city\n" ] } ], "source": [ "neighborhood = 'ALPHABET CITY'\n", "\n", "print(f\"neighborhood.title() : {neighborhood.title()}\")\n", "print(f\"neighborhood.capitalize() : {neighborhood.capitalize()}\")" ] }, { "cell_type": "markdown", "id": "d19ad72f", "metadata": {}, "source": [ "What's the difference?! Well, for the astute observers, you may have noticed that `title()` capitlizes the first letter of every word in the string while `capitalize()` capitlizes the first letter of the entire string. Since we're dealing with the names of neighborhoods, we want to use `title()`.\n", "\n", "Let's use `apply()` function to apply `title()` to each row in our dataframe. We can do this by applying an anoynmous/lambda function.\n", "\n", "#### What is an anonymous function? \n", "\n", "It's a one-liner function without a name. Unlike traditional functions in Python that use `def` followed by the function name, an anonymous function uses the `lambda` keyword. It's useful when we only need to use the function once. This is how the syntax looks:" ] }, { "cell_type": "code", "execution_count": 31, "id": "df8a1b78", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/var/folders/c6/66vf07tn12b7f11fct15gggm0000gn/T/ipykernel_91911/2317548855.py:1: SettingWithCopyWarning: \n", "A value is trying to be set on a copy of a slice from a DataFrame.\n", "Try using .loc[row_indexer,col_indexer] = value instead\n", "\n", "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n", " df_filtered['neighborhood'] = df_filtered['neighborhood'].apply(lambda x: x.title())\n" ] } ], "source": [ "df_filtered['neighborhood'] = df_filtered['neighborhood'].apply(lambda x: x.title())" ] }, { "cell_type": "markdown", "id": "e316d774", "metadata": {}, "source": [ "With the code above, we're basically looking at each row of the `neighborhood` column, and applying \"`title()`\" to the row value. We don't need to do any for-loops - the `apply()` iterates through each value for us. \n", "\n", "Let's check out the output of our newly formatted `neighborhood` column:" ] }, { "cell_type": "code", "execution_count": 32, "id": "d6287306", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "41535 Madison\n", "38337 Flatbush-East\n", "8080 Midtown East\n", "78066 Grant City\n", "37530 Flatbush-Central\n", "Name: neighborhood, dtype: object" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_filtered['neighborhood'].sample(5)" ] }, { "cell_type": "markdown", "id": "442846ff", "metadata": {}, "source": [ "The neighborhood values look so much better after applying `title()`. " ] }, { "cell_type": "markdown", "id": "4502f2b8", "metadata": {}, "source": [ "### Building Class Category\n", "\n", "Now, let's move onto the `building_class_category` which is a bit more complicated to format. We want to make 2 modifications to this column:\n", "\n", "1. remove the number at start of the name \n", "2. capitalize the string value\n", "\n", "Since this is a two-step process, we'll create a real function instead of an anonymous one like we did for the `neighborhood` column.\n", "\n", "It's easier if we break this down into steps so let's start by splitting the `building_class_category` string into a list:" ] }, { "cell_type": "code", "execution_count": 33, "id": "9d8bebda", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['07', 'RENTALS', '-', 'WALKUP', 'APARTMENTS']" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "building_class_category = '07 RENTALS - WALKUP APARTMENTS'\n", "\n", "building_class_category_list = building_class_category.split(' ')\n", "building_class_category_list" ] }, { "cell_type": "markdown", "id": "c011af7b", "metadata": {}, "source": [ "We want to remove the first element of the output above. We can do this by slicing the list to start at index 1 instead of index 0:" ] }, { "cell_type": "code", "execution_count": 34, "id": "d0f52264", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['RENTALS', '-', 'WALKUP', 'APARTMENTS']" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "building_class_category_list[1:]" ] }, { "cell_type": "markdown", "id": "314333fe", "metadata": {}, "source": [ "Woohoo! We can now rejoin the list into a single string:" ] }, { "cell_type": "code", "execution_count": 35, "id": "6468c7ff", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'RENTALS - WALKUP APARTMENTS'" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "' '.join(building_class_category_list[1:])" ] }, { "cell_type": "markdown", "id": "662924f8", "metadata": {}, "source": [ "Lastly, we can convert the string from uppercase to a capitlized version like this:" ] }, { "cell_type": "code", "execution_count": 36, "id": "6fb5f151", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'Rentals - walkup apartments'" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "' '.join(building_class_category_list[1:]).capitalize()" ] }, { "cell_type": "markdown", "id": "56d2a484", "metadata": {}, "source": [ "Let's combine all this logic into one function:" ] }, { "cell_type": "code", "execution_count": 37, "id": "d14432f4", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'Rentals - walkup apartments'" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def format_building_class_category(text):\n", " text_list = text.split(' ')\n", " clean_text = ' '.join(text_list[1:])\n", " clean_text_capitalized = clean_text.capitalize()\n", " return clean_text_capitalized.capitalize()\n", "\n", "format_building_class_category(building_class_category)" ] }, { "cell_type": "markdown", "id": "d4f453de", "metadata": {}, "source": [ "Now, we can apply this function to every row in the `building_class_category` column." ] }, { "cell_type": "code", "execution_count": 38, "id": "c8f42081", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/var/folders/c6/66vf07tn12b7f11fct15gggm0000gn/T/ipykernel_91911/1079090973.py:1: SettingWithCopyWarning: \n", "A value is trying to be set on a copy of a slice from a DataFrame.\n", "Try using .loc[row_indexer,col_indexer] = value instead\n", "\n", "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n", " df_filtered['building_class_category'] = df_filtered['building_class_category'].apply(format_building_class_category)\n" ] } ], "source": [ "df_filtered['building_class_category'] = df_filtered['building_class_category'].apply(format_building_class_category)" ] }, { "cell_type": "code", "execution_count": 39, "id": "a0c0b1d8", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'Rentals - walkup apartments '" ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_filtered['building_class_category'][0]" ] }, { "cell_type": "markdown", "id": "30db2f71", "metadata": {}, "source": [ "Hmmm ๐ค. It looks like this column has a lot of trailing whitespace. We can fix this by applying the `strip()` function which is meant to remove any whitespace on the left or right side of a string." ] }, { "cell_type": "code", "execution_count": 40, "id": "2a0350d9", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'Rentals - walkup apartments'" ] }, "execution_count": 40, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_filtered['building_class_category'][0].strip()" ] }, { "cell_type": "markdown", "id": "56842695", "metadata": {}, "source": [ "Looks good! Let's apply this to all of our column values by applying the lambda function. " ] }, { "cell_type": "code", "execution_count": 41, "id": "1f6595c0", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/var/folders/c6/66vf07tn12b7f11fct15gggm0000gn/T/ipykernel_91911/2294236723.py:1: SettingWithCopyWarning: \n", "A value is trying to be set on a copy of a slice from a DataFrame.\n", "Try using .loc[row_indexer,col_indexer] = value instead\n", "\n", "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n", " df_filtered['building_class_category'] = df_filtered['building_class_category'].apply(lambda x: x.strip())\n" ] } ], "source": [ "df_filtered['building_class_category'] = df_filtered['building_class_category'].apply(lambda x: x.strip())" ] }, { "cell_type": "markdown", "id": "69963699", "metadata": {}, "source": [ "How does it look?" ] }, { "cell_type": "code", "execution_count": 42, "id": "52d8d220", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'Rentals - walkup apartments'" ] }, "execution_count": 42, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_filtered['building_class_category'][0]" ] }, { "cell_type": "markdown", "id": "d30e4e4a", "metadata": {}, "source": [ "Just as expected - our newly formatted `building_class_category` column has the prefixed number removed, is capitalized (instead of all uppercase) and doesn't have any trailing whitespace. " ] }, { "cell_type": "markdown", "id": "c980a2ba", "metadata": {}, "source": [ "## 8) Merging dataframes together" ] }, { "cell_type": "markdown", "id": "4221fe65", "metadata": {}, "source": [ "If two datasets have a shared column, you can combine them together to create a more robust dataset. In SQL, this is done using the **JOIN** statement. With Pandas, this is done using the [**`.merge()`**](https://pandas.pydata.org/docs/reference/api/pandas.merge.html) function. \n", "\n", "Let's see how this works with our particular dataset. You may noticed that we have two columns that represent building class codes:\n", "\n", "1. `building_class_at_present` \n", "2. `building_class_at_time_of_sale`" ] }, { "cell_type": "code", "execution_count": 43, "id": "b676e9ec", "metadata": {}, "outputs": [ { "data": { "text/html": [ "<div>\n", "<style scoped>\n", " .dataframe tbody tr th:only-of-type {\n", " vertical-align: middle;\n", " }\n", "\n", " .dataframe tbody tr th {\n", " vertical-align: top;\n", " }\n", "\n", " .dataframe thead th {\n", " text-align: right;\n", " }\n", "</style>\n", "<table border=\"1\" class=\"dataframe\">\n", " <thead>\n", " <tr style=\"text-align: right;\">\n", " <th></th>\n", " <th>building_class_at_present</th>\n", " <th>building_class_at_time_of_sale</th>\n", " </tr>\n", " </thead>\n", " <tbody>\n", " <tr>\n", " <th>0</th>\n", " <td>C2</td>\n", " <td>C2</td>\n", " </tr>\n", " <tr>\n", " <th>3</th>\n", " <td>C4</td>\n", " <td>C4</td>\n", " </tr>\n", " <tr>\n", " <th>4</th>\n", " <td>C2</td>\n", " <td>C2</td>\n", " </tr>\n", " <tr>\n", " <th>6</th>\n", " <td>C4</td>\n", " <td>C4</td>\n", " </tr>\n", " <tr>\n", " <th>9</th>\n", " <td>D9</td>\n", " <td>D9</td>\n", " </tr>\n", " </tbody>\n", "</table>\n", "</div>" ], "text/plain": [ " building_class_at_present building_class_at_time_of_sale\n", "0 C2 C2\n", "3 C4 C4\n", "4 C2 C2\n", "6 C4 C4\n", "9 D9 D9" ] }, "execution_count": 43, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df[['building_class_at_present', 'building_class_at_time_of_sale']].head()" ] }, { "cell_type": "markdown", "id": "e16266bc", "metadata": {}, "source": [ "These building class codes have a corresponding description, which is documented in this [City of NYC building code glossary](https://www1.nyc.gov/assets/finance/jump/hlpbldgcode.html). We have this stored in a psv (pipe-separated value) file which we can load in using pandas' `read_csv()` function. Let's name this new dataframe `building_code_description`.\n", "\n", "```{note}\n", "Unlike the csv file, where values are separated by commas, the pipe-separate value (psv) file is separated by the pipe, `|`. By default, pandas' `read_csv()` function assumes the separator is a comma. We will need to specify that the separator is a pipe, `|` using the `sep` argument.\n", "```" ] }, { "cell_type": "code", "execution_count": 44, "id": "b0329ec0", "metadata": {}, "outputs": [ { "data": { "text/html": [ "<div>\n", "<style scoped>\n", " .dataframe tbody tr th:only-of-type {\n", " vertical-align: middle;\n", " }\n", "\n", " .dataframe tbody tr th {\n", " vertical-align: top;\n", " }\n", "\n", " .dataframe thead th {\n", " text-align: right;\n", " }\n", "</style>\n", "<table border=\"1\" class=\"dataframe\">\n", " <thead>\n", " <tr style=\"text-align: right;\">\n", " <th></th>\n", " <th>building_class_code</th>\n", " <th>description</th>\n", " </tr>\n", " </thead>\n", " <tbody>\n", " <tr>\n", " <th>0</th>\n", " <td>A0</td>\n", " <td>CAPE COD</td>\n", " </tr>\n", " <tr>\n", " <th>1</th>\n", " <td>A1</td>\n", " <td>TWO STORIES - DETACHED SM OR MID</td>\n", " </tr>\n", " <tr>\n", " <th>2</th>\n", " <td>A2</td>\n", " <td>ONE STORY - PERMANENT LIVING QUARTER</td>\n", " </tr>\n", " <tr>\n", " <th>3</th>\n", " <td>A3</td>\n", " <td>LARGE SUBURBAN RESIDENCE</td>\n", " </tr>\n", " <tr>\n", " <th>4</th>\n", " <td>A4</td>\n", " <td>CITY RESIDENCE ONE FAMILY</td>\n", " </tr>\n", " </tbody>\n", "</table>\n", "</div>" ], "text/plain": [ " building_class_code description\n", "0 A0 CAPE COD\n", "1 A1 TWO STORIES - DETACHED SM OR MID\n", "2 A2 ONE STORY - PERMANENT LIVING QUARTER\n", "3 A3 LARGE SUBURBAN RESIDENCE\n", "4 A4 CITY RESIDENCE ONE FAMILY" ] }, "execution_count": 44, "metadata": {}, "output_type": "execute_result" } ], "source": [ "building_codes = pd.read_csv(\"data/building_class.psv\", sep='|')\n", "building_codes.head()" ] }, { "cell_type": "markdown", "id": "5796af32", "metadata": {}, "source": [ "Despite their different names, the \"building_class_code\", \"building_class_at_present\", and \"building_class_at_time_of_sale\" columns all represent the same thing: the building code of a property. We can use this new dataframe to enhance our original dataframe by providing the building class descriptions instead of relying solely on the code which is hard to interpet." ] }, { "cell_type": "markdown", "id": "a7cce8fe", "metadata": {}, "source": [ "*But* first - let's clean up the building code descrption by switching the text from all uppercase to capitlized. " ] }, { "cell_type": "code", "execution_count": 45, "id": "d7cbce32", "metadata": {}, "outputs": [], "source": [ "building_codes['description'] = building_codes['description'].apply(lambda x: x.capitalize())" ] }, { "cell_type": "markdown", "id": "0e12d5bf", "metadata": {}, "source": [ "Now, we can merge (or \"join\") the \"building_code_description\" dataframe with our original dataset. We need to join it twice, for 2 columns:\n", "\n", "1. `building_class_at_time_of_sale`\n", "2. `building_class_at_present`\n", "\n", "A join works by matching the values of one dataframe (let's called it the Left DataFrame) with the values of another dataframe (the Right DataFrame). It's important that the two joining dataframes share a common column; this is what gets used for the matching. In the illustration below, the green column is the common column shared between the Left and Right DataFrames.\n", "\n", "<img width='60%' src=\"assets/join_tables_example.png\"/>\n", "\n", "### Types of Join\n", "\n", "What happens when the common column between two tables isn't the \"perfect match\"? For example, what if the Left DataFrame has a value that isn't found in the Right DataFrame, or vice versa? We will need to decide how to handle this by choosing what type of join to apply. There are several types of joins to choose from: \n", "\n", "1. **Inner join:** Returns rows when there is a match in both dataframes. \n", " - If the Left DataFrame has a value that isn't found in the Right DataFrame, we would drop the rows having that value in the Left DataFrame. \n", "2. **Left join:** Returns all rows from the Left DataFrame, even if there are no matches in the Right DataFrame.\n", " - If the Left DataFrame has a value that isn't found in the Right DataFrame, we would keep the rows having this value but in the resulting dataframe, those rows would have null (missing) values for the columns associated with the Right DataFrame. We would drop the rows of the Right DataFrame taht don't match the Left DataFrame.\n", "3. **Right join:** Returns all rows from the Right DataFrame, even if there are no matches in the Left DataFrame.\n", " - Same logic as the left join but this time, we keep all rows from the Right DataFrame. We would drop the rows of the Left DataFrame that don't match the Right DataFrame. \n", "4. **Full outer join:** Returns all rows from the Left and Right DataFrames even if there are no matches between them. \n", " - This can result in a very large dataset!\n", "\n", "### Overview of the Joins\n", "\n", "<img width=\"85%\" src=\"assets/joins_overview.png\"/>\n", "\n", "```{note}\n", "Based on personal experience, I find that the `left join` and `inner join` are the most common types of joins used in data science. It's quite rare to see the `right join` and `full outer join` in the wild.\n", "```\n", "\n", "### Applying `.merge()` to the data\n", "\n", "We can apply this join technique onto our Pandas DataFrames using the `.merge()` function. This is how the syntax looks:\n", "\n", "```\n", "CombinedDataFrame = LeftDataFrame.merge(RightDataFrame, how='left', left_on='left_col', right_on='right_col')\n", "```\n", "\n", "The RightDataFrame is merged onto the LeftDataFrame using `.merge()`. This is what the parameters inside of `.merge()` represent:\n", "\n", "- `how` indicates which type of join you want to apply. Options include: 'inner', 'left', 'right', 'outer', 'cross'. The default is 'inner'.\n", "- `left_on` indicates the common column of the Left DataFrame and `right_on` represents the common column of the Right DataFrame\n", "- If both dataframes have the same name for the common column, you can simply use `on` (and omit `left_on` and `right_on`)\n", "\n", "In our particular case, we'll be merging our original dataframe (which we call the \"Left DataFrame\") onto the building code dataframe (the Right DataFrame). Let's see how it looks in action:" ] }, { "cell_type": "code", "execution_count": 46, "id": "4caf7046", "metadata": {}, "outputs": [], "source": [ "combined_dataframe = (\n", " df_filtered.merge(\n", " building_codes.rename(columns={\n", " 'building_class_code': 'building_class_at_present',\n", " 'description': 'building_description_at_present'\n", " }), \n", " how='left', \n", " on='building_class_at_present'\n", " )\n", " .merge(\n", " building_codes.rename(columns={\n", " 'building_class_code': 'building_class_at_time_of_sale',\n", " 'description': 'building_description_at_time_of_sale'\n", " }), \n", " how='left', \n", " on='building_class_at_time_of_sale', \n", " )\n", ")" ] }, { "cell_type": "markdown", "id": "a02c50bf", "metadata": {}, "source": [ "In the code above, we chained 2 merges one after the next because we wanted to join `building_class` onto our original dataframe twice: 1) on \"building_class_at_present\" and 2) on \"building_class_at_time_of_sale\". To make things easier with the merge, we also renamed \"building_class_code\" for each merge so that the column in `building_class` matched what was in the original dataframe. This allowed us to simply use the `on` argument when identifying the common column instead of having to use `left_on` and `right_on`. " ] }, { "cell_type": "code", "execution_count": 47, "id": "f9cc86f1", "metadata": {}, "outputs": [ { "data": { "text/html": [ "<div>\n", "<style scoped>\n", " .dataframe tbody tr th:only-of-type {\n", " vertical-align: middle;\n", " }\n", "\n", " .dataframe tbody tr th {\n", " vertical-align: top;\n", " }\n", "\n", " .dataframe thead th {\n", " text-align: right;\n", " }\n", "</style>\n", "<table border=\"1\" class=\"dataframe\">\n", " <thead>\n", " <tr style=\"text-align: right;\">\n", " <th></th>\n", " <th>borough</th>\n", " <th>neighborhood</th>\n", " <th>building_class_category</th>\n", " <th>building_class_at_present</th>\n", " <th>address</th>\n", " <th>apartment_number</th>\n", " <th>zip_code</th>\n", " <th>residential_units</th>\n", " <th>commercial_units</th>\n", " <th>total_units</th>\n", " <th>land_square_feet</th>\n", " <th>gross_square_feet</th>\n", " <th>year_built</th>\n", " <th>building_class_at_time_of_sale</th>\n", " <th>sale_price</th>\n", " <th>sale_date</th>\n", " <th>building_description_at_present</th>\n", " <th>building_description_at_time_of_sale</th>\n", " </tr>\n", " </thead>\n", " <tbody>\n", " <tr>\n", " <th>0</th>\n", " <td>Manhattan</td>\n", " <td>Alphabet City</td>\n", " <td>Rentals - walkup apartments</td>\n", " <td>C2</td>\n", " <td>153 AVENUE B</td>\n", " <td></td>\n", " <td>10009</td>\n", " <td>5</td>\n", " <td>0</td>\n", " <td>5</td>\n", " <td>1633.0</td>\n", " <td>6440.0</td>\n", " <td>1900</td>\n", " <td>C2</td>\n", " <td>6625000.0</td>\n", " <td>2017-07-19</td>\n", " <td>Five to six families</td>\n", " <td>Five to six families</td>\n", " </tr>\n", " <tr>\n", " <th>1</th>\n", " <td>Manhattan</td>\n", " <td>Alphabet City</td>\n", " <td>Rentals - walkup apartments</td>\n", " <td>C4</td>\n", " <td>154 EAST 7TH STREET</td>\n", " <td></td>\n", " <td>10009</td>\n", " <td>10</td>\n", " <td>0</td>\n", " <td>10</td>\n", " <td>2272.0</td>\n", " <td>6794.0</td>\n", " <td>1913</td>\n", " <td>C4</td>\n", " <td>3936272.0</td>\n", " <td>2016-09-23</td>\n", " <td>Old law tenement</td>\n", " <td>Old law tenement</td>\n", " </tr>\n", " <tr>\n", " <th>2</th>\n", " <td>Manhattan</td>\n", " <td>Alphabet City</td>\n", " <td>Rentals - walkup apartments</td>\n", " <td>C2</td>\n", " <td>301 EAST 10TH STREET</td>\n", " <td></td>\n", " <td>10009</td>\n", " <td>6</td>\n", " <td>0</td>\n", " <td>6</td>\n", " <td>2369.0</td>\n", " <td>4615.0</td>\n", " <td>1900</td>\n", " <td>C2</td>\n", " <td>8000000.0</td>\n", " <td>2016-11-17</td>\n", " <td>Five to six families</td>\n", " <td>Five to six families</td>\n", " </tr>\n", " <tr>\n", " <th>3</th>\n", " <td>Manhattan</td>\n", " <td>Alphabet City</td>\n", " <td>Rentals - walkup apartments</td>\n", " <td>C4</td>\n", " <td>210 AVENUE B</td>\n", " <td></td>\n", " <td>10009</td>\n", " <td>8</td>\n", " <td>0</td>\n", " <td>8</td>\n", " <td>1750.0</td>\n", " <td>4226.0</td>\n", " <td>1920</td>\n", " <td>C4</td>\n", " <td>3192840.0</td>\n", " <td>2016-09-23</td>\n", " <td>Old law tenement</td>\n", " <td>Old law tenement</td>\n", " </tr>\n", " <tr>\n", " <th>4</th>\n", " <td>Manhattan</td>\n", " <td>Alphabet City</td>\n", " <td>Rentals - elevator apartments</td>\n", " <td>D9</td>\n", " <td>629 EAST 5TH STREET</td>\n", " <td></td>\n", " <td>10009</td>\n", " <td>24</td>\n", " <td>0</td>\n", " <td>24</td>\n", " <td>4489.0</td>\n", " <td>18523.0</td>\n", " <td>1920</td>\n", " <td>D9</td>\n", " <td>16232000.0</td>\n", " <td>2016-11-07</td>\n", " <td>Elevator apt; miscellaneous</td>\n", " <td>Elevator apt; miscellaneous</td>\n", " </tr>\n", " </tbody>\n", "</table>\n", "</div>" ], "text/plain": [ " borough neighborhood building_class_category \\\n", "0 Manhattan Alphabet City Rentals - walkup apartments \n", "1 Manhattan Alphabet City Rentals - walkup apartments \n", "2 Manhattan Alphabet City Rentals - walkup apartments \n", "3 Manhattan Alphabet City Rentals - walkup apartments \n", "4 Manhattan Alphabet City Rentals - elevator apartments \n", "\n", " building_class_at_present address apartment_number \\\n", "0 C2 153 AVENUE B \n", "1 C4 154 EAST 7TH STREET \n", "2 C2 301 EAST 10TH STREET \n", "3 C4 210 AVENUE B \n", "4 D9 629 EAST 5TH STREET \n", "\n", " zip_code residential_units commercial_units total_units \\\n", "0 10009 5 0 5 \n", "1 10009 10 0 10 \n", "2 10009 6 0 6 \n", "3 10009 8 0 8 \n", "4 10009 24 0 24 \n", "\n", " land_square_feet gross_square_feet year_built \\\n", "0 1633.0 6440.0 1900 \n", "1 2272.0 6794.0 1913 \n", "2 2369.0 4615.0 1900 \n", "3 1750.0 4226.0 1920 \n", "4 4489.0 18523.0 1920 \n", "\n", " building_class_at_time_of_sale sale_price sale_date \\\n", "0 C2 6625000.0 2017-07-19 \n", "1 C4 3936272.0 2016-09-23 \n", "2 C2 8000000.0 2016-11-17 \n", "3 C4 3192840.0 2016-09-23 \n", "4 D9 16232000.0 2016-11-07 \n", "\n", " building_description_at_present building_description_at_time_of_sale \n", "0 Five to six families Five to six families \n", "1 Old law tenement Old law tenement \n", "2 Five to six families Five to six families \n", "3 Old law tenement Old law tenement \n", "4 Elevator apt; miscellaneous Elevator apt; miscellaneous " ] }, "execution_count": 47, "metadata": {}, "output_type": "execute_result" } ], "source": [ "combined_dataframe.head()" ] }, { "cell_type": "markdown", "id": "0e89bb86", "metadata": {}, "source": [ "If you scroll to the very right, you'll see two new columns: \"building_description_at_present\" and \"building_description_at_time_of_sale\", which resulted from our merged dataframes in the code above.\n", "\n", "<img src=\"https://media.giphy.com/media/FNJ6MX0nn8lfW/giphy.gif\"/>" ] }, { "cell_type": "markdown", "id": "cc51b84c", "metadata": {}, "source": [ "## 9) Writing the clean dataframe to a new csv file \n", "\n", "We have a clean dataset that we can start exploring. To load the clean version of our dataframe into another Jupyter Notebook, we will need to save it as a csv file ๐พ. To do this, we can use `.to_csv()`. Inside `.to_csv()`, we need to specify the location where we want the csv file to be saved:" ] }, { "cell_type": "code", "execution_count": 48, "id": "224ef54c", "metadata": {}, "outputs": [], "source": [ "combined_dataframe.to_csv(\"data/nyc_real_estate_clean.csv\", index=False)" ] }, { "cell_type": "markdown", "id": "c3725d89", "metadata": {}, "source": [ "By default, there's an `index` argument which is set to True. With this setting, the index is included as a separate column in the csv file. For our dataset, we don't want this extra index column so we set `index` to False.\n", "\n", "<img width=\"70%\" src=\"assets/to_csv_index_output.png\"/>" ] } ], "metadata": { "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.12" } }, "nbformat": 4, "nbformat_minor": 5 }