{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "

Toronto Neighborhood Map

" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Step 1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

***Textbook Created*** " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Step 2 " ] }, { "cell_type": "code", "execution_count": 109, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Requirement already satisfied: lxml in /home/jupyterlab/conda/envs/python/lib/python3.6/site-packages (4.5.1)\n", "Requirement already satisfied: beautifulsoup4 in /home/jupyterlab/conda/envs/python/lib/python3.6/site-packages (4.9.1)\n", "Requirement already satisfied: soupsieve>1.2 in /home/jupyterlab/conda/envs/python/lib/python3.6/site-packages (from beautifulsoup4) (2.0.1)\n", "Requirement already satisfied: geocoder in /home/jupyterlab/conda/envs/python/lib/python3.6/site-packages (1.38.1)\n", "Requirement already satisfied: click in /home/jupyterlab/conda/envs/python/lib/python3.6/site-packages (from geocoder) (7.1.2)\n", "Requirement already satisfied: requests in /home/jupyterlab/conda/envs/python/lib/python3.6/site-packages (from geocoder) (2.23.0)\n", "Requirement already satisfied: ratelim in /home/jupyterlab/conda/envs/python/lib/python3.6/site-packages (from geocoder) (0.1.6)\n", "Requirement already satisfied: six in /home/jupyterlab/conda/envs/python/lib/python3.6/site-packages (from geocoder) (1.14.0)\n", "Requirement already satisfied: future in /home/jupyterlab/conda/envs/python/lib/python3.6/site-packages (from geocoder) (0.18.2)\n", "Requirement already satisfied: chardet<4,>=3.0.2 in /home/jupyterlab/conda/envs/python/lib/python3.6/site-packages (from requests->geocoder) (3.0.4)\n", "Requirement already satisfied: certifi>=2017.4.17 in /home/jupyterlab/conda/envs/python/lib/python3.6/site-packages (from requests->geocoder) (2020.4.5.1)\n", "Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /home/jupyterlab/conda/envs/python/lib/python3.6/site-packages (from requests->geocoder) (1.25.9)\n", "Requirement already satisfied: idna<3,>=2.5 in /home/jupyterlab/conda/envs/python/lib/python3.6/site-packages (from requests->geocoder) (2.9)\n", "Requirement already satisfied: decorator in /home/jupyterlab/conda/envs/python/lib/python3.6/site-packages (from ratelim->geocoder) (4.4.2)\n" ] } ], "source": [ "import numpy as np \n", "import pandas as pd \n", "import requests \n", "import folium\n", "!pip install lxml\n", "!pip install beautifulsoup4\n", "!pip install geocoder" ] }, { "cell_type": "code", "execution_count": 94, "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", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Postal CodeBoroughNeighborhood
0M1ANot assignedNot assigned
1M2ANot assignedNot assigned
2M3ANorth YorkParkwoods
3M4ANorth YorkVictoria Village
4M5ADowntown TorontoRegent Park, Harbourfront
5M6ANorth YorkLawrence Manor, Lawrence Heights
6M7ADowntown TorontoQueen's Park, Ontario Provincial Government
7M8ANot assignedNot assigned
8M9AEtobicokeIslington Avenue, Humber Valley Village
9M1BScarboroughMalvern, Rouge
10M2BNot assignedNot assigned
11M3BNorth YorkDon Mills
12M4BEast YorkParkview Hill, Woodbine Gardens
13M5BDowntown TorontoGarden District, Ryerson
14M6BNorth YorkGlencairn
\n", "
" ], "text/plain": [ " Postal Code Borough Neighborhood\n", "0 M1A Not assigned Not assigned\n", "1 M2A Not assigned Not assigned\n", "2 M3A North York Parkwoods\n", "3 M4A North York Victoria Village\n", "4 M5A Downtown Toronto Regent Park, Harbourfront\n", "5 M6A North York Lawrence Manor, Lawrence Heights\n", "6 M7A Downtown Toronto Queen's Park, Ontario Provincial Government\n", "7 M8A Not assigned Not assigned\n", "8 M9A Etobicoke Islington Avenue, Humber Valley Village\n", "9 M1B Scarborough Malvern, Rouge\n", "10 M2B Not assigned Not assigned\n", "11 M3B North York Don Mills\n", "12 M4B East York Parkview Hill, Woodbine Gardens\n", "13 M5B Downtown Toronto Garden District, Ryerson\n", "14 M6B North York Glencairn" ] }, "execution_count": 94, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df = pd.read_html('https://en.wikipedia.org/wiki/List_of_postal_codes_of_Canada:_M')[0]\n", "df.head(15)" ] }, { "cell_type": "code", "execution_count": 95, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Postal Code object\n", "Borough object\n", "Neighborhood object\n", "dtype: object" ] }, "execution_count": 95, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.dtypes" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Step 3 " ] }, { "cell_type": "code", "execution_count": 99, "metadata": {}, "outputs": [], "source": [ "#Only process the cells that have an assigned borough. Ignore cells with a borough that is Not assigned. - [X]\n", "\n", "df.drop(df[df['Borough']==\"Not assigned\"].index,axis=0, inplace=True)\n", "\n", "#More than one neighborhood can exist in one postal code area. For example, in the table on the Wikipedia page, \n", "#you will notice that M5A is listed twice and has two neighborhoods: Harbourfront and Regent Park. \n", "#These two rows will be combined into one row with the neighborhoods separated with a comma as shown in row 11 in \n", "#the above table.\n", "\n", "df['Neighborhood'] = df.groupby(\"Postal Code\")[\"Neighborhood\"].transform(lambda neigh: ', '.join(neigh))\n", "\n", "#If a cell has a borough but a Not assigned neighborhood, then the neighborhood will be the same as the borough.\n", "\n", "df['Neighborhood'].replace(\"Not assigned\", df[\"Borough\"],inplace=True)" ] }, { "cell_type": "code", "execution_count": 102, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(103, 3)" ] }, "execution_count": 102, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.shape" ] }, { "cell_type": "code", "execution_count": 103, "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", "
Postal CodeBoroughNeighborhood
2M3ANorth YorkParkwoods
3M4ANorth YorkVictoria Village
4M5ADowntown TorontoRegent Park, Harbourfront
5M6ANorth YorkLawrence Manor, Lawrence Heights
6M7ADowntown TorontoQueen's Park, Ontario Provincial Government
\n", "
" ], "text/plain": [ " Postal Code Borough Neighborhood\n", "2 M3A North York Parkwoods\n", "3 M4A North York Victoria Village\n", "4 M5A Downtown Toronto Regent Park, Harbourfront\n", "5 M6A North York Lawrence Manor, Lawrence Heights\n", "6 M7A Downtown Toronto Queen's Park, Ontario Provincial Government" ] }, "execution_count": 103, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Stage 2 " ] }, { "cell_type": "code", "execution_count": 104, "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", "
Postal CodeLatitudeLongitude
0M1B43.806686-79.194353
1M1C43.784535-79.160497
2M1E43.763573-79.188711
3M1G43.770992-79.216917
4M1H43.773136-79.239476
\n", "
" ], "text/plain": [ " Postal Code Latitude Longitude\n", "0 M1B 43.806686 -79.194353\n", "1 M1C 43.784535 -79.160497\n", "2 M1E 43.763573 -79.188711\n", "3 M1G 43.770992 -79.216917\n", "4 M1H 43.773136 -79.239476" ] }, "execution_count": 104, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Now that you have built a dataframe of the postal code of each neighborhood along with \n", "# the borough name and neighborhood name, in order to utilize the Foursquare location data, \n", "# we need to get the latitude and the longitude coordinates of each neighborhood.\n", "\n", "df2 = pd.read_csv(\"https://cocl.us/Geospatial_data\")\n", "df2.head()" ] }, { "cell_type": "code", "execution_count": 105, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Postal Code object\n", "Latitude float64\n", "Longitude float64\n", "dtype: object" ] }, "execution_count": 105, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df2.dtypes" ] }, { "cell_type": "code", "execution_count": 108, "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", " \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", "
Postal CodeBoroughNeighborhoodLatitudeLongitude
0M3ANorth YorkParkwoods43.753259-79.329656
1M4ANorth YorkVictoria Village43.725882-79.315572
2M5ADowntown TorontoRegent Park, Harbourfront43.654260-79.360636
3M6ANorth YorkLawrence Manor, Lawrence Heights43.718518-79.464763
4M7ADowntown TorontoQueen's Park, Ontario Provincial Government43.662301-79.389494
5M9AEtobicokeIslington Avenue, Humber Valley Village43.667856-79.532242
6M1BScarboroughMalvern, Rouge43.806686-79.194353
7M3BNorth YorkDon Mills43.745906-79.352188
8M4BEast YorkParkview Hill, Woodbine Gardens43.706397-79.309937
9M5BDowntown TorontoGarden District, Ryerson43.657162-79.378937
10M6BNorth YorkGlencairn43.709577-79.445073
11M9BEtobicokeWest Deane Park, Princess Gardens, Martin Grov...43.650943-79.554724
12M1CScarboroughRouge Hill, Port Union, Highland Creek43.784535-79.160497
13M3CNorth YorkDon Mills43.725900-79.340923
14M4CEast YorkWoodbine Heights43.695344-79.318389
\n", "
" ], "text/plain": [ " Postal Code Borough \\\n", "0 M3A North York \n", "1 M4A North York \n", "2 M5A Downtown Toronto \n", "3 M6A North York \n", "4 M7A Downtown Toronto \n", "5 M9A Etobicoke \n", "6 M1B Scarborough \n", "7 M3B North York \n", "8 M4B East York \n", "9 M5B Downtown Toronto \n", "10 M6B North York \n", "11 M9B Etobicoke \n", "12 M1C Scarborough \n", "13 M3C North York \n", "14 M4C East York \n", "\n", " Neighborhood Latitude Longitude \n", "0 Parkwoods 43.753259 -79.329656 \n", "1 Victoria Village 43.725882 -79.315572 \n", "2 Regent Park, Harbourfront 43.654260 -79.360636 \n", "3 Lawrence Manor, Lawrence Heights 43.718518 -79.464763 \n", "4 Queen's Park, Ontario Provincial Government 43.662301 -79.389494 \n", "5 Islington Avenue, Humber Valley Village 43.667856 -79.532242 \n", "6 Malvern, Rouge 43.806686 -79.194353 \n", "7 Don Mills 43.745906 -79.352188 \n", "8 Parkview Hill, Woodbine Gardens 43.706397 -79.309937 \n", "9 Garden District, Ryerson 43.657162 -79.378937 \n", "10 Glencairn 43.709577 -79.445073 \n", "11 West Deane Park, Princess Gardens, Martin Grov... 43.650943 -79.554724 \n", "12 Rouge Hill, Port Union, Highland Creek 43.784535 -79.160497 \n", "13 Don Mills 43.725900 -79.340923 \n", "14 Woodbine Heights 43.695344 -79.318389 " ] }, "execution_count": 108, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df3 = pd.merge(df, df2, on='Postal Code')\n", "df3.head(15)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Stage 3 " ] }, { "cell_type": "code", "execution_count": 111, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Collecting package metadata (current_repodata.json): done\n", "Solving environment: done\n", "\n", "## Package Plan ##\n", "\n", " environment location: /home/jupyterlab/conda/envs/python\n", "\n", " added / updated specs:\n", " - geopy\n", "\n", "\n", "The following packages will be downloaded:\n", "\n", " package | build\n", " ---------------------------|-----------------\n", " ca-certificates-2020.4.5.2 | hecda079_0 147 KB conda-forge\n", " certifi-2020.4.5.2 | py36h9f0ad1d_0 152 KB conda-forge\n", " geographiclib-1.50 | py_0 34 KB conda-forge\n", " geopy-1.22.0 | pyh9f0ad1d_0 63 KB conda-forge\n", " ------------------------------------------------------------\n", " Total: 395 KB\n", "\n", "The following NEW packages will be INSTALLED:\n", "\n", " geographiclib conda-forge/noarch::geographiclib-1.50-py_0\n", " geopy conda-forge/noarch::geopy-1.22.0-pyh9f0ad1d_0\n", "\n", "The following packages will be UPDATED:\n", "\n", " ca-certificates 2020.4.5.1-hecc5488_0 --> 2020.4.5.2-hecda079_0\n", " certifi 2020.4.5.1-py36h9f0ad1d_0 --> 2020.4.5.2-py36h9f0ad1d_0\n", "\n", "\n", "\n", "Downloading and Extracting Packages\n", "geopy-1.22.0 | 63 KB | ##################################### | 100% \n", "certifi-2020.4.5.2 | 152 KB | ##################################### | 100% \n", "ca-certificates-2020 | 147 KB | ##################################### | 100% \n", "geographiclib-1.50 | 34 KB | ##################################### | 100% \n", "Preparing transaction: done\n", "Verifying transaction: done\n", "Executing transaction: done\n", "Collecting package metadata (current_repodata.json): done\n", "Solving environment: failed with initial frozen solve. Retrying with flexible solve.\n", "Collecting package metadata (repodata.json): done\n", "Solving environment: | ^C\n", "failed with initial frozen solve. Retrying with flexible solve.\n", "\n", "CondaError: KeyboardInterrupt\n", "\n", "Libraries imported.\n" ] } ], "source": [ "import numpy as np \n", "import pandas as pd \n", "pd.set_option('display.max_columns', None)\n", "pd.set_option('display.max_rows', None)\n", "import json \n", "!conda install -c conda-forge geopy --yes\n", "from geopy.geocoders import Nominatim \n", "import requests \n", "from pandas.io.json import json_normalize \n", "import matplotlib.cm as cm\n", "import matplotlib.colors as colors\n", "from sklearn.cluster import KMeans\n", "!conda install -c conda-forge folium=0.5.0 --yes\n", "import folium \n", "print('Libraries imported.')" ] }, { "cell_type": "code", "execution_count": 121, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The dataframe has 10 boroughs and 103 postal codes.\n" ] } ], "source": [ "print('The dataframe has {} boroughs and {} postal codes.'.format(\n", " len(df3['Borough'].unique()),\n", " df3.shape[0]))" ] }, { "cell_type": "code", "execution_count": 122, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The geograpical coordinate of Toronto are 43.6534817, -79.3839347.\n" ] } ], "source": [ "address = 'Toronto, CA'\n", "\n", "geolocator = Nominatim(user_agent=\"ny_explorer\")\n", "location = geolocator.geocode(address)\n", "latitude = location.latitude\n", "longitude = location.longitude\n", "print('The geograpical coordinate of Toronto are {}, {}.'.format(latitude, longitude))" ] }, { "cell_type": "code", "execution_count": 124, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
Make this Notebook Trusted to load map: File -> Trust Notebook
" ], "text/plain": [ "" ] }, "execution_count": 124, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Toronto_map = folium.Map(location=[latitude, longitude], zoom_start=10)\n", "\n", "for lat, lng, borough, neighborhood in zip(df3['Latitude'], df3['Longitude'], df3['Borough'], df3['Neighborhood']):\n", " label = '{}, {}'.format(neighborhood, borough)\n", " label = folium.Popup(label, parse_html=True)\n", " folium.CircleMarker(\n", " [lat, lng],\n", " radius=5,\n", " popup=label,\n", " color='blue',\n", " fill=True,\n", " fill_color='#3186cc',\n", " fill_opacity=0.7,\n", " parse_html=False).add_to(Toronto_map) \n", " \n", "Toronto_map" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "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.8.5" } }, "nbformat": 4, "nbformat_minor": 4 }