Skip to content

Instantly share code, notes, and snippets.

@bertrandobi
Created April 4, 2019 12:43
Show Gist options
  • Save bertrandobi/075062cf2d9f02742b280ae6d5fa98c8 to your computer and use it in GitHub Desktop.
Save bertrandobi/075062cf2d9f02742b280ae6d5fa98c8 to your computer and use it in GitHub Desktop.
Created on Cognitive Class Labs
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## BUSINESS DENSITY ANALYSIS IN PARIS FRANCE"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Problem Statement"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Even when Entrepreneurs posses the capital required in setting up a business. Choosing the right location that can attract potential customers for the business is a major decision to make. Even when a city is chosen, it requires further business density analysis or neighbourhood analysis in order to choose a suitable neigbourhood for the business."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Background"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This project will be implemented in Paris - France, owing to the fact that its the Capital city of France and a historic touristic city. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Target Audience"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This project could be use by the following individuals:\n",
" 1. Business persons with interest in setting up small businesses in Paris\n",
" 2. Customers looking for where to obtain particular services in Paris\n",
" 3. Tourists interested in visiting and spending quality time in Paris for the first time\n",
" 4. Paris city administration interested in channelling balance business set ups in particular neighbourhoods in the city\n",
" 5. Government interested in balance developments in the city of Paris."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Project Objectives:"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- Build a dataframe of neighborhoods in Paris - France by web scraping the data from Wikipedia page\n",
"- Get the geographical coordinates of the neighborhoods using the geocoder function\n",
"- Obtain the venue data for the neighborhoods from Foursquare API\n",
"- Explore and cluster the neighborhoods\n",
"- Select the best cluster to open a new business"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Import Libraries necessary for the project"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Libraries imported!\n"
]
}
],
"source": [
"import urllib.request # open and read URLs\n",
"import json # handle JSON files\n",
"from pandas.io.json import json_normalize # tranform JSON file into a pandas dataframe\n",
"import requests # handle requests\n",
"import pandas as pd # process data as dataframes with Pandas\n",
"import numpy as np # handle data in a vectorized manner with NumPy\n",
"# !conda install -c conda-forge geopy --yes # uncomment this line if you haven't installed the GeoPy geocoding library yet\n",
"from geopy.geocoders import Nominatim # convert an address into latitude and longitude values\n",
"# !conda install -c conda-forge folium=0.5.0 --yes # uncomment this line if you haven't installed the Folium library yet\n",
"import folium # map rendering library\n",
"# Matplolib plotting library and associated modules\n",
"import matplotlib.pyplot as plt \n",
"import matplotlib.cm as cm\n",
"import matplotlib.colors as colors\n",
"from sklearn.cluster import KMeans # for K-Means clustering with Scikit-Learn\n",
"print(\"Libraries imported!\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Connect to a csv file containing open data on Paris Neighbourhoods(Arrondissements) and transform to a Dataframe"
]
},
{
"cell_type": "code",
"execution_count": 3,
"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>Arrondissement</th>\n",
" <th>Neighborhood</th>\n",
" <th>Latitude</th>\n",
" <th>Longitude</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>1</td>\n",
" <td>Louvre</td>\n",
" <td>48.862563</td>\n",
" <td>2.336443</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>2</td>\n",
" <td>Bourse</td>\n",
" <td>48.868279</td>\n",
" <td>2.342803</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>3</td>\n",
" <td>Temple</td>\n",
" <td>48.862872</td>\n",
" <td>2.360001</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>4</td>\n",
" <td>Hôtel-de-Ville</td>\n",
" <td>48.854341</td>\n",
" <td>2.357630</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>5</td>\n",
" <td>Panthéon</td>\n",
" <td>48.844443</td>\n",
" <td>2.350715</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>6</td>\n",
" <td>Luxembourg</td>\n",
" <td>48.849130</td>\n",
" <td>2.332898</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td>7</td>\n",
" <td>Palais-Bourbon</td>\n",
" <td>48.856174</td>\n",
" <td>2.312188</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7</th>\n",
" <td>8</td>\n",
" <td>Elysée</td>\n",
" <td>48.872721</td>\n",
" <td>2.312554</td>\n",
" </tr>\n",
" <tr>\n",
" <th>8</th>\n",
" <td>9</td>\n",
" <td>Opéra</td>\n",
" <td>48.877164</td>\n",
" <td>2.337458</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9</th>\n",
" <td>10</td>\n",
" <td>Entrepôt</td>\n",
" <td>48.876130</td>\n",
" <td>2.360728</td>\n",
" </tr>\n",
" <tr>\n",
" <th>10</th>\n",
" <td>11</td>\n",
" <td>Popincourt</td>\n",
" <td>48.859059</td>\n",
" <td>2.380058</td>\n",
" </tr>\n",
" <tr>\n",
" <th>11</th>\n",
" <td>12</td>\n",
" <td>Reuilly</td>\n",
" <td>48.834974</td>\n",
" <td>2.421325</td>\n",
" </tr>\n",
" <tr>\n",
" <th>12</th>\n",
" <td>13</td>\n",
" <td>Gobelins</td>\n",
" <td>48.828388</td>\n",
" <td>2.362272</td>\n",
" </tr>\n",
" <tr>\n",
" <th>13</th>\n",
" <td>14</td>\n",
" <td>Observatoire</td>\n",
" <td>48.829245</td>\n",
" <td>2.326542</td>\n",
" </tr>\n",
" <tr>\n",
" <th>14</th>\n",
" <td>15</td>\n",
" <td>Vaugirard</td>\n",
" <td>48.840085</td>\n",
" <td>2.292826</td>\n",
" </tr>\n",
" <tr>\n",
" <th>15</th>\n",
" <td>16</td>\n",
" <td>Passy</td>\n",
" <td>48.860392</td>\n",
" <td>2.261971</td>\n",
" </tr>\n",
" <tr>\n",
" <th>16</th>\n",
" <td>17</td>\n",
" <td>Batignolles-Monceau</td>\n",
" <td>48.887327</td>\n",
" <td>2.306777</td>\n",
" </tr>\n",
" <tr>\n",
" <th>17</th>\n",
" <td>18</td>\n",
" <td>Buttes-Montmartre</td>\n",
" <td>48.892569</td>\n",
" <td>2.348161</td>\n",
" </tr>\n",
" <tr>\n",
" <th>18</th>\n",
" <td>19</td>\n",
" <td>Buttes-Chaumont</td>\n",
" <td>48.887076</td>\n",
" <td>2.384821</td>\n",
" </tr>\n",
" <tr>\n",
" <th>19</th>\n",
" <td>20</td>\n",
" <td>Ménilmontant</td>\n",
" <td>48.863461</td>\n",
" <td>2.401188</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Arrondissement Neighborhood Latitude Longitude\n",
"0 1 Louvre 48.862563 2.336443\n",
"1 2 Bourse 48.868279 2.342803\n",
"2 3 Temple 48.862872 2.360001\n",
"3 4 Hôtel-de-Ville 48.854341 2.357630\n",
"4 5 Panthéon 48.844443 2.350715\n",
"5 6 Luxembourg 48.849130 2.332898\n",
"6 7 Palais-Bourbon 48.856174 2.312188\n",
"7 8 Elysée 48.872721 2.312554\n",
"8 9 Opéra 48.877164 2.337458\n",
"9 10 Entrepôt 48.876130 2.360728\n",
"10 11 Popincourt 48.859059 2.380058\n",
"11 12 Reuilly 48.834974 2.421325\n",
"12 13 Gobelins 48.828388 2.362272\n",
"13 14 Observatoire 48.829245 2.326542\n",
"14 15 Vaugirard 48.840085 2.292826\n",
"15 16 Passy 48.860392 2.261971\n",
"16 17 Batignolles-Monceau 48.887327 2.306777\n",
"17 18 Buttes-Montmartre 48.892569 2.348161\n",
"18 19 Buttes-Chaumont 48.887076 2.384821\n",
"19 20 Ménilmontant 48.863461 2.401188"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"dfs = pd.read_csv('arrondissements.csv', sep=';')\n",
"df=dfs[['C_AR', 'L_AR', 'L_AROFF', 'Geometry X Y']]\n",
"df[['Latitude','Longitude']]=df['Geometry X Y'].str.split(\",\",expand=True,)\n",
"df[['Latitude','Longitude']] = df[['Latitude','Longitude']].astype(float)\n",
"df1 = df.drop(df[['L_AR', 'Geometry X Y']], axis=1)\n",
"df1.columns = ['Arrondissement', 'Neighborhood', 'Latitude', 'Longitude']\n",
"paris_data = df1.sort_values([\"Arrondissement\"]).reset_index(drop=True)\n",
"paris_data.loc[paris_data.Neighborhood == \"Élysée\", [\"Neighborhood\"]] = \"Elysée\"\n",
"paris_data"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Use GeoPy library to get the geographical coordinates of Paris"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"The geograpical coordinates of Paris are 48.8566101, 2.3514992.\n"
]
}
],
"source": [
"address = \"Paris, FR\"\n",
"geolocator = Nominatim(user_agent=\"my-application\")\n",
"location_par = geolocator.geocode(address)\n",
"latitude_par = location_par.latitude\n",
"longitude_par = location_par.longitude\n",
"print(\"The geograpical coordinates of Paris are {}, {}.\".format(latitude_par, longitude_par))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Visualise Paris on a Map"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div style=\"width:100%;\"><div style=\"position:relative;width:100%;height:0;padding-bottom:60%;\"><iframe src=\"data:text/html;charset=utf-8;base64,PCFET0NUWVBFIGh0bWw+CjxoZWFkPiAgICAKICAgIDxtZXRhIGh0dHAtZXF1aXY9ImNvbnRlbnQtdHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PVVURi04IiAvPgogICAgPHNjcmlwdD5MX1BSRUZFUl9DQU5WQVMgPSBmYWxzZTsgTF9OT19UT1VDSCA9IGZhbHNlOyBMX0RJU0FCTEVfM0QgPSBmYWxzZTs8L3NjcmlwdD4KICAgIDxzY3JpcHQgc3JjPSJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL2xlYWZsZXRAMS4yLjAvZGlzdC9sZWFmbGV0LmpzIj48L3NjcmlwdD4KICAgIDxzY3JpcHQgc3JjPSJodHRwczovL2FqYXguZ29vZ2xlYXBpcy5jb20vYWpheC9saWJzL2pxdWVyeS8xLjExLjEvanF1ZXJ5Lm1pbi5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IHNyYz0iaHR0cHM6Ly9tYXhjZG4uYm9vdHN0cmFwY2RuLmNvbS9ib290c3RyYXAvMy4yLjAvanMvYm9vdHN0cmFwLm1pbi5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IHNyYz0iaHR0cHM6Ly9jZG5qcy5jbG91ZGZsYXJlLmNvbS9hamF4L2xpYnMvTGVhZmxldC5hd2Vzb21lLW1hcmtlcnMvMi4wLjIvbGVhZmxldC5hd2Vzb21lLW1hcmtlcnMuanMiPjwvc2NyaXB0PgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL2xlYWZsZXRAMS4yLjAvZGlzdC9sZWFmbGV0LmNzcyIvPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL21heGNkbi5ib290c3RyYXBjZG4uY29tL2Jvb3RzdHJhcC8zLjIuMC9jc3MvYm9vdHN0cmFwLm1pbi5jc3MiLz4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cHM6Ly9tYXhjZG4uYm9vdHN0cmFwY2RuLmNvbS9ib290c3RyYXAvMy4yLjAvY3NzL2Jvb3RzdHJhcC10aGVtZS5taW4uY3NzIi8+CiAgICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9Imh0dHBzOi8vbWF4Y2RuLmJvb3RzdHJhcGNkbi5jb20vZm9udC1hd2Vzb21lLzQuNi4zL2Nzcy9mb250LWF3ZXNvbWUubWluLmNzcyIvPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL2NkbmpzLmNsb3VkZmxhcmUuY29tL2FqYXgvbGlicy9MZWFmbGV0LmF3ZXNvbWUtbWFya2Vycy8yLjAuMi9sZWFmbGV0LmF3ZXNvbWUtbWFya2Vycy5jc3MiLz4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cHM6Ly9yYXdnaXQuY29tL3B5dGhvbi12aXN1YWxpemF0aW9uL2ZvbGl1bS9tYXN0ZXIvZm9saXVtL3RlbXBsYXRlcy9sZWFmbGV0LmF3ZXNvbWUucm90YXRlLmNzcyIvPgogICAgPHN0eWxlPmh0bWwsIGJvZHkge3dpZHRoOiAxMDAlO2hlaWdodDogMTAwJTttYXJnaW46IDA7cGFkZGluZzogMDt9PC9zdHlsZT4KICAgIDxzdHlsZT4jbWFwIHtwb3NpdGlvbjphYnNvbHV0ZTt0b3A6MDtib3R0b206MDtyaWdodDowO2xlZnQ6MDt9PC9zdHlsZT4KICAgIAogICAgICAgICAgICA8c3R5bGU+ICNtYXBfMjBiYjJhODZhYTFjNDQ2Y2I0NDRmOTEwYzY2ZTAxNWIgewogICAgICAgICAgICAgICAgcG9zaXRpb24gOiByZWxhdGl2ZTsKICAgICAgICAgICAgICAgIHdpZHRoIDogMTAwLjAlOwogICAgICAgICAgICAgICAgaGVpZ2h0OiAxMDAuMCU7CiAgICAgICAgICAgICAgICBsZWZ0OiAwLjAlOwogICAgICAgICAgICAgICAgdG9wOiAwLjAlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICA8L3N0eWxlPgogICAgICAgIAo8L2hlYWQ+Cjxib2R5PiAgICAKICAgIAogICAgICAgICAgICA8ZGl2IGNsYXNzPSJmb2xpdW0tbWFwIiBpZD0ibWFwXzIwYmIyYTg2YWExYzQ0NmNiNDQ0ZjkxMGM2NmUwMTViIiA+PC9kaXY+CiAgICAgICAgCjwvYm9keT4KPHNjcmlwdD4gICAgCiAgICAKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGJvdW5kcyA9IG51bGw7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgdmFyIG1hcF8yMGJiMmE4NmFhMWM0NDZjYjQ0NGY5MTBjNjZlMDE1YiA9IEwubWFwKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ21hcF8yMGJiMmE4NmFhMWM0NDZjYjQ0NGY5MTBjNjZlMDE1YicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7Y2VudGVyOiBbNDguODU2NjEwMSwyLjM1MTQ5OTJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgem9vbTogMTIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXhCb3VuZHM6IGJvdW5kcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxheWVyczogW10sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3b3JsZENvcHlKdW1wOiBmYWxzZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNyczogTC5DUlMuRVBTRzM4NTcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciB0aWxlX2xheWVyXzMxYmNjMDA1ZTQ0MDRiMzI4OGNkY2RmNGFhMGVmNDcxID0gTC50aWxlTGF5ZXIoCiAgICAgICAgICAgICAgICAnaHR0cHM6Ly97c30udGlsZS5vcGVuc3RyZWV0bWFwLm9yZy97en0ve3h9L3t5fS5wbmcnLAogICAgICAgICAgICAgICAgewogICJhdHRyaWJ1dGlvbiI6IG51bGwsCiAgImRldGVjdFJldGluYSI6IGZhbHNlLAogICJtYXhab29tIjogMTgsCiAgIm1pblpvb20iOiAxLAogICJub1dyYXAiOiBmYWxzZSwKICAic3ViZG9tYWlucyI6ICJhYmMiCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzIwYmIyYTg2YWExYzQ0NmNiNDQ0ZjkxMGM2NmUwMTViKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9mNzViMTVmZDRkNDE0NjBiOTUwODk4MWI5ZTJkNWMzMSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQ4Ljg2MjU2MjcwMTgsMi4zMzY0NDMzNjIwNV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF8yMGJiMmE4NmFhMWM0NDZjYjQ0NGY5MTBjNjZlMDE1Yik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF82MGFjZTBlZjBlYTk0MGVhOWJmYmQ5ZDM5YTU1OGNmMSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9mYTFiYTU3OTBhZDc0Y2UzYmZmMjQ3YjY4Mzk5NzhiZCA9ICQoJzxkaXYgaWQ9Imh0bWxfZmExYmE1NzkwYWQ3NGNlM2JmZjI0N2I2ODM5OTc4YmQiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjEsIExvdXZyZTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNjBhY2UwZWYwZWE5NDBlYTliZmJkOWQzOWE1NThjZjEuc2V0Q29udGVudChodG1sX2ZhMWJhNTc5MGFkNzRjZTNiZmYyNDdiNjgzOTk3OGJkKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2Y3NWIxNWZkNGQ0MTQ2MGI5NTA4OTgxYjllMmQ1YzMxLmJpbmRQb3B1cChwb3B1cF82MGFjZTBlZjBlYTk0MGVhOWJmYmQ5ZDM5YTU1OGNmMSk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9mMWRlYjNmN2ZhNGI0YzFkOTNhNzg3NjVjMjdiMGNjZCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQ4Ljg2ODI3OTIyMjUsMi4zNDI4MDI1NDY4OV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF8yMGJiMmE4NmFhMWM0NDZjYjQ0NGY5MTBjNjZlMDE1Yik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9kM2IwNWNjZmIwZGY0ZGE5OGY5YTFhOTQ1ZTU0YTkyMCA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF85ODg0ZGU5YWYyY2E0Yzc1ODAxZWFiM2I1YzljZjg1NiA9ICQoJzxkaXYgaWQ9Imh0bWxfOTg4NGRlOWFmMmNhNGM3NTgwMWVhYjNiNWM5Y2Y4NTYiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjIsIEJvdXJzZTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfZDNiMDVjY2ZiMGRmNGRhOThmOWExYTk0NWU1NGE5MjAuc2V0Q29udGVudChodG1sXzk4ODRkZTlhZjJjYTRjNzU4MDFlYWIzYjVjOWNmODU2KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2YxZGViM2Y3ZmE0YjRjMWQ5M2E3ODc2NWMyN2IwY2NkLmJpbmRQb3B1cChwb3B1cF9kM2IwNWNjZmIwZGY0ZGE5OGY5YTFhOTQ1ZTU0YTkyMCk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8zMTNlZmJkNDM3MTQ0OTMxYjU5M2M0NzQ4YWIwYTg5NCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQ4Ljg2Mjg3MjM4LDIuMzYwMDAwOTg1OV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF8yMGJiMmE4NmFhMWM0NDZjYjQ0NGY5MTBjNjZlMDE1Yik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF84NDcyMjE1OTJmMjU0OGU2YTgwZWJjYTIwMTliNTdiOSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9iZWU5Y2JkODg0NGU0NzRhODRjY2I0MTJlYjVmOTdkZSA9ICQoJzxkaXYgaWQ9Imh0bWxfYmVlOWNiZDg4NDRlNDc0YTg0Y2NiNDEyZWI1Zjk3ZGUiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjMsIFRlbXBsZTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfODQ3MjIxNTkyZjI1NDhlNmE4MGViY2EyMDE5YjU3Yjkuc2V0Q29udGVudChodG1sX2JlZTljYmQ4ODQ0ZTQ3NGE4NGNjYjQxMmViNWY5N2RlKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzMxM2VmYmQ0MzcxNDQ5MzFiNTkzYzQ3NDhhYjBhODk0LmJpbmRQb3B1cChwb3B1cF84NDcyMjE1OTJmMjU0OGU2YTgwZWJjYTIwMTliNTdiOSk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9iMTFlYjViYzAxYjQ0MmJhYjljZjdjMTE4NDc4NzgzZSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQ4Ljg1NDM0MTQyNjMsMi4zNTc2Mjk2MjAzMl0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF8yMGJiMmE4NmFhMWM0NDZjYjQ0NGY5MTBjNjZlMDE1Yik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9mYWExOWE3N2MwMjY0NDNlOGIyNTNjYTQ3NTFiOTE3YSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9iNDM5NzI0ZjExNmY0OGZhOTA3NTYyZWE2NGExNDUzNiA9ICQoJzxkaXYgaWQ9Imh0bWxfYjQzOTcyNGYxMTZmNDhmYTkwNzU2MmVhNjRhMTQ1MzYiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjQsIEjDtHRlbC1kZS1WaWxsZTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfZmFhMTlhNzdjMDI2NDQzZThiMjUzY2E0NzUxYjkxN2Euc2V0Q29udGVudChodG1sX2I0Mzk3MjRmMTE2ZjQ4ZmE5MDc1NjJlYTY0YTE0NTM2KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2IxMWViNWJjMDFiNDQyYmFiOWNmN2MxMTg0Nzg3ODNlLmJpbmRQb3B1cChwb3B1cF9mYWExOWE3N2MwMjY0NDNlOGIyNTNjYTQ3NTFiOTE3YSk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl80ZGEyZWE2NTk4ODc0MzY1YmE0MzVkYzM5MzQ4YTg1YSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQ4Ljg0NDQ0MzE1MDUsMi4zNTA3MTQ2MDk1OF0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF8yMGJiMmE4NmFhMWM0NDZjYjQ0NGY5MTBjNjZlMDE1Yik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9hMWM5MmE1ZDcyY2Y0YjFiOTZlYTBkZTI1YzU4NjIxOSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9jYzVmYjFhNDAyMjA0OGUxYWIxY2IwY2QxZjRmZDkzMyA9ICQoJzxkaXYgaWQ9Imh0bWxfY2M1ZmIxYTQwMjIwNDhlMWFiMWNiMGNkMWY0ZmQ5MzMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjUsIFBhbnRow6lvbjwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfYTFjOTJhNWQ3MmNmNGIxYjk2ZWEwZGUyNWM1ODYyMTkuc2V0Q29udGVudChodG1sX2NjNWZiMWE0MDIyMDQ4ZTFhYjFjYjBjZDFmNGZkOTMzKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzRkYTJlYTY1OTg4NzQzNjViYTQzNWRjMzkzNDhhODVhLmJpbmRQb3B1cChwb3B1cF9hMWM5MmE1ZDcyY2Y0YjFiOTZlYTBkZTI1YzU4NjIxOSk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl84YmY5MzRhNTJjOTc0Zjk2YjAzNDA1MTJhM2RlNzZhYiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQ4Ljg0OTEzMDM1ODYsMi4zMzI4OTc5OTkwNV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF8yMGJiMmE4NmFhMWM0NDZjYjQ0NGY5MTBjNjZlMDE1Yik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9hZmNkM2M1OWRhMDE0Y2IyYWQ0ZTM0MDllNDVmYTRkOCA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9jNjU1NjM0YzEzZjk0OGE0YmJlZjJmYjk4ZjNmZmJmYyA9ICQoJzxkaXYgaWQ9Imh0bWxfYzY1NTYzNGMxM2Y5NDhhNGJiZWYyZmI5OGYzZmZiZmMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjYsIEx1eGVtYm91cmc8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2FmY2QzYzU5ZGEwMTRjYjJhZDRlMzQwOWU0NWZhNGQ4LnNldENvbnRlbnQoaHRtbF9jNjU1NjM0YzEzZjk0OGE0YmJlZjJmYjk4ZjNmZmJmYyk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl84YmY5MzRhNTJjOTc0Zjk2YjAzNDA1MTJhM2RlNzZhYi5iaW5kUG9wdXAocG9wdXBfYWZjZDNjNTlkYTAxNGNiMmFkNGUzNDA5ZTQ1ZmE0ZDgpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNGQzMmQyOTQyMDY1NDgyZDlhNDZhZWI1ZDZkZGQwOTkgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0OC44NTYxNzQ0Mjg4LDIuMzEyMTg3NjkxNDhdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfMjBiYjJhODZhYTFjNDQ2Y2I0NDRmOTEwYzY2ZTAxNWIpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfY2ZjNDdkMzgzYWEzNDVlOThmNzllNjE1NjlhNDIyM2UgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZDljMDU2Nzc2ZTY5NDQ1ZTkxZTI3NTVlOTExM2ViMTEgPSAkKCc8ZGl2IGlkPSJodG1sX2Q5YzA1Njc3NmU2OTQ0NWU5MWUyNzU1ZTkxMTNlYjExIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij43LCBQYWxhaXMtQm91cmJvbjwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfY2ZjNDdkMzgzYWEzNDVlOThmNzllNjE1NjlhNDIyM2Uuc2V0Q29udGVudChodG1sX2Q5YzA1Njc3NmU2OTQ0NWU5MWUyNzU1ZTkxMTNlYjExKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzRkMzJkMjk0MjA2NTQ4MmQ5YTQ2YWViNWQ2ZGRkMDk5LmJpbmRQb3B1cChwb3B1cF9jZmM0N2QzODNhYTM0NWU5OGY3OWU2MTU2OWE0MjIzZSk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl9lYWRkYmJjYjYzZmU0ZmU3YTQ3YjJkOGRkYmZhZjM3YyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQ4Ljg3MjcyMDgzNzQsMi4zMTI1NTQwMjI0XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzIwYmIyYTg2YWExYzQ0NmNiNDQ0ZjkxMGM2NmUwMTViKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2ZjY2RhMDE4N2VkNjQ2NDc4ZDE2ZmViYTlkM2Q5NjM4ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzg1NmJiZmI2ZjFlZjQ5NmE5MjA5NmFmMTBkN2RhYTkyID0gJCgnPGRpdiBpZD0iaHRtbF84NTZiYmZiNmYxZWY0OTZhOTIwOTZhZjEwZDdkYWE5MiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+OCwgRWx5c8OpZTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfZmNjZGEwMTg3ZWQ2NDY0NzhkMTZmZWJhOWQzZDk2Mzguc2V0Q29udGVudChodG1sXzg1NmJiZmI2ZjFlZjQ5NmE5MjA5NmFmMTBkN2RhYTkyKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2VhZGRiYmNiNjNmZTRmZTdhNDdiMmQ4ZGRiZmFmMzdjLmJpbmRQb3B1cChwb3B1cF9mY2NkYTAxODdlZDY0NjQ3OGQxNmZlYmE5ZDNkOTYzOCk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl80ZDI4YmE4NzUyZjg0ZjBkYTZlN2FiOWU1ZTI4ZjdiMSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQ4Ljg3NzE2MzUxNzMsMi4zMzc0NTc1NDM0OF0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF8yMGJiMmE4NmFhMWM0NDZjYjQ0NGY5MTBjNjZlMDE1Yik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9mZTQ2YzUxZWQ5NWI0Y2M3OTY2MmU5ZGZhNjNmMTVmZSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9mNDgyNTdjOWQ2OGU0ZjIyYjQyMDM4ZjA4N2NhZTdmNCA9ICQoJzxkaXYgaWQ9Imh0bWxfZjQ4MjU3YzlkNjhlNGYyMmI0MjAzOGYwODdjYWU3ZjQiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjksIE9ww6lyYTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfZmU0NmM1MWVkOTViNGNjNzk2NjJlOWRmYTYzZjE1ZmUuc2V0Q29udGVudChodG1sX2Y0ODI1N2M5ZDY4ZTRmMjJiNDIwMzhmMDg3Y2FlN2Y0KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzRkMjhiYTg3NTJmODRmMGRhNmU3YWI5ZTVlMjhmN2IxLmJpbmRQb3B1cChwb3B1cF9mZTQ2YzUxZWQ5NWI0Y2M3OTY2MmU5ZGZhNjNmMTVmZSk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8yZGQ5MjczNjUwMzQ0MjY1OTFkMWM4NDI5MGFkZmZiZiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQ4Ljg3NjEzMDAzNjUsMi4zNjA3Mjg0ODc4NV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF8yMGJiMmE4NmFhMWM0NDZjYjQ0NGY5MTBjNjZlMDE1Yik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF83MmRhOWJhZDk4NjE0MmU2YTA2MmIyZjkzZWE2MGQ3YiA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF80NzhmYTI5MTE1ODc0MjY0YTQ4OGZlYmRjMmI3NzNiNiA9ICQoJzxkaXYgaWQ9Imh0bWxfNDc4ZmEyOTExNTg3NDI2NGE0ODhmZWJkYzJiNzczYjYiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjEwLCBFbnRyZXDDtHQ8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzcyZGE5YmFkOTg2MTQyZTZhMDYyYjJmOTNlYTYwZDdiLnNldENvbnRlbnQoaHRtbF80NzhmYTI5MTE1ODc0MjY0YTQ4OGZlYmRjMmI3NzNiNik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl8yZGQ5MjczNjUwMzQ0MjY1OTFkMWM4NDI5MGFkZmZiZi5iaW5kUG9wdXAocG9wdXBfNzJkYTliYWQ5ODYxNDJlNmEwNjJiMmY5M2VhNjBkN2IpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYWQ1ZGQ4OGZmMWMxNDY1MmFhNzdjZjg1OGZhOTc0NGMgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0OC44NTkwNTkyMjEzLDIuMzgwMDU4MzA4Ml0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF8yMGJiMmE4NmFhMWM0NDZjYjQ0NGY5MTBjNjZlMDE1Yik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9jNjQyZWRiYzMwMWI0YzliYmNkMGQyNTUxYTMzOTMyZSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9lZGIzNzA2NjVmN2Q0ZTQ4ODcwMTJhMmVkYmNkOWM0MSA9ICQoJzxkaXYgaWQ9Imh0bWxfZWRiMzcwNjY1ZjdkNGU0ODg3MDEyYTJlZGJjZDljNDEiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjExLCBQb3BpbmNvdXJ0PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9jNjQyZWRiYzMwMWI0YzliYmNkMGQyNTUxYTMzOTMyZS5zZXRDb250ZW50KGh0bWxfZWRiMzcwNjY1ZjdkNGU0ODg3MDEyYTJlZGJjZDljNDEpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfYWQ1ZGQ4OGZmMWMxNDY1MmFhNzdjZjg1OGZhOTc0NGMuYmluZFBvcHVwKHBvcHVwX2M2NDJlZGJjMzAxYjRjOWJiY2QwZDI1NTFhMzM5MzJlKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzllOGNlN2JkZjYzMzRlN2M4YmQ3NTJkNWE0MjhiNzY0ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDguODM0OTc0MzgxNSwyLjQyMTMyNDkwMDc4XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzIwYmIyYTg2YWExYzQ0NmNiNDQ0ZjkxMGM2NmUwMTViKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzc3N2E1OGI1OTFiZTQwNGU5ZWQzMDg0NjVmZWNmOTNmID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzRlYjcwMzY0NzI4YTRhYTFhMzk2NzFlMzVmMjgxNmIxID0gJCgnPGRpdiBpZD0iaHRtbF80ZWI3MDM2NDcyOGE0YWExYTM5NjcxZTM1ZjI4MTZiMSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+MTIsIFJldWlsbHk8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzc3N2E1OGI1OTFiZTQwNGU5ZWQzMDg0NjVmZWNmOTNmLnNldENvbnRlbnQoaHRtbF80ZWI3MDM2NDcyOGE0YWExYTM5NjcxZTM1ZjI4MTZiMSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl85ZThjZTdiZGY2MzM0ZTdjOGJkNzUyZDVhNDI4Yjc2NC5iaW5kUG9wdXAocG9wdXBfNzc3YTU4YjU5MWJlNDA0ZTllZDMwODQ2NWZlY2Y5M2YpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNWZkYmEwMjRjMzZjNGY4MWEzNDQ4YThjMWFjMzY5MmEgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0OC44MjgzODgwMzE3LDIuMzYyMjcyNDQwNDJdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfMjBiYjJhODZhYTFjNDQ2Y2I0NDRmOTEwYzY2ZTAxNWIpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNzlhMWY0ZWQxNzZmNGY0Yzk4OWIxNGU1MDNhNWQxNjQgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfODNhZTkxNzZmMjJlNDkxOTg3MDEzZjFjNWZkN2FhZjIgPSAkKCc8ZGl2IGlkPSJodG1sXzgzYWU5MTc2ZjIyZTQ5MTk4NzAxM2YxYzVmZDdhYWYyIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij4xMywgR29iZWxpbnM8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzc5YTFmNGVkMTc2ZjRmNGM5ODliMTRlNTAzYTVkMTY0LnNldENvbnRlbnQoaHRtbF84M2FlOTE3NmYyMmU0OTE5ODcwMTNmMWM1ZmQ3YWFmMik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl81ZmRiYTAyNGMzNmM0ZjgxYTM0NDhhOGMxYWMzNjkyYS5iaW5kUG9wdXAocG9wdXBfNzlhMWY0ZWQxNzZmNGY0Yzk4OWIxNGU1MDNhNWQxNjQpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNDk5MWM5ZjBkNjc3NGY1ZmFiYjBjNjA2YTkyNzAyY2MgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0OC44MjkyNDQ1MDA1LDIuMzI2NTQyMDQ0Ml0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF8yMGJiMmE4NmFhMWM0NDZjYjQ0NGY5MTBjNjZlMDE1Yik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF80ZDQ5ZmQ2MDRlNjg0OTU4OTA2OTk2YjJmZmEzOTUwMiA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF82YTcwOTRlZjcyZTE0ODg4OTA0YzA2ZDI4NWVlMTBiMyA9ICQoJzxkaXYgaWQ9Imh0bWxfNmE3MDk0ZWY3MmUxNDg4ODkwNGMwNmQyODVlZTEwYjMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjE0LCBPYnNlcnZhdG9pcmU8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzRkNDlmZDYwNGU2ODQ5NTg5MDY5OTZiMmZmYTM5NTAyLnNldENvbnRlbnQoaHRtbF82YTcwOTRlZjcyZTE0ODg4OTA0YzA2ZDI4NWVlMTBiMyk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl80OTkxYzlmMGQ2Nzc0ZjVmYWJiMGM2MDZhOTI3MDJjYy5iaW5kUG9wdXAocG9wdXBfNGQ0OWZkNjA0ZTY4NDk1ODkwNjk5NmIyZmZhMzk1MDIpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNDJmZmM4OGI4YzIwNDQ4YjkxZmEwZTA2MjdlNWQ4ODQgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0OC44NDAwODUzNzU5LDIuMjkyODI1ODIyNDJdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfMjBiYjJhODZhYTFjNDQ2Y2I0NDRmOTEwYzY2ZTAxNWIpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfY2Q5MjI3ZGJmYTEwNDEzYWE5Zjk2MjQzYzAwYjgyYzggPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNGY0Y2MyYTI5NDVlNDNhMTg4ODgxNThhMjg4NDRkZDEgPSAkKCc8ZGl2IGlkPSJodG1sXzRmNGNjMmEyOTQ1ZTQzYTE4ODg4MTU4YTI4ODQ0ZGQxIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij4xNSwgVmF1Z2lyYXJkPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9jZDkyMjdkYmZhMTA0MTNhYTlmOTYyNDNjMDBiODJjOC5zZXRDb250ZW50KGh0bWxfNGY0Y2MyYTI5NDVlNDNhMTg4ODgxNThhMjg4NDRkZDEpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfNDJmZmM4OGI4YzIwNDQ4YjkxZmEwZTA2MjdlNWQ4ODQuYmluZFBvcHVwKHBvcHVwX2NkOTIyN2RiZmExMDQxM2FhOWY5NjI0M2MwMGI4MmM4KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2I2Njc3N2RhMjY5ZTQ1M2RiMTQwY2U5ZDllYTI3ZjA4ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDguODYwMzkyMTA1NCwyLjI2MTk3MDc4ODM2XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzIwYmIyYTg2YWExYzQ0NmNiNDQ0ZjkxMGM2NmUwMTViKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzU0Y2IxNTZhOGQ5OTQ5YmVhMDkzMjg0NjNhODQ1YTkyID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzBlMGI0MmFmNzI2YTQ4NDBiNjViMzFhODM1ZjE1NTBmID0gJCgnPGRpdiBpZD0iaHRtbF8wZTBiNDJhZjcyNmE0ODQwYjY1YjMxYTgzNWYxNTUwZiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+MTYsIFBhc3N5PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF81NGNiMTU2YThkOTk0OWJlYTA5MzI4NDYzYTg0NWE5Mi5zZXRDb250ZW50KGh0bWxfMGUwYjQyYWY3MjZhNDg0MGI2NWIzMWE4MzVmMTU1MGYpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfYjY2Nzc3ZGEyNjllNDUzZGIxNDBjZTlkOWVhMjdmMDguYmluZFBvcHVwKHBvcHVwXzU0Y2IxNTZhOGQ5OTQ5YmVhMDkzMjg0NjNhODQ1YTkyKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzYxZGNlOTg1MjlkMDQzZjhhNThmODI4NzkzZjZjOWIxID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDguODg3MzI2NTIyLDIuMzA2Nzc2OTkwNTddLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiYmx1ZSIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiMzMTg2Y2MiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfMjBiYjJhODZhYTFjNDQ2Y2I0NDRmOTEwYzY2ZTAxNWIpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfMGEyNWJhNGI5MDg3NGYzOWE1MDFjNmI4NGNjZDA3ZDIgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfN2MxYjVkZGIyZGRiNDc5MjhjYjAzZmQ0MjI2Y2QyZmMgPSAkKCc8ZGl2IGlkPSJodG1sXzdjMWI1ZGRiMmRkYjQ3OTI4Y2IwM2ZkNDIyNmNkMmZjIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij4xNywgQmF0aWdub2xsZXMtTW9uY2VhdTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMGEyNWJhNGI5MDg3NGYzOWE1MDFjNmI4NGNjZDA3ZDIuc2V0Q29udGVudChodG1sXzdjMWI1ZGRiMmRkYjQ3OTI4Y2IwM2ZkNDIyNmNkMmZjKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzYxZGNlOTg1MjlkMDQzZjhhNThmODI4NzkzZjZjOWIxLmJpbmRQb3B1cChwb3B1cF8wYTI1YmE0YjkwODc0ZjM5YTUwMWM2Yjg0Y2NkMDdkMik7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl84MjE2NjgwYTRhZjI0MTY1OWYwYzgyNGI2MzYxYmE2MiA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQ4Ljg5MjU2OTI2OCwyLjM0ODE2MDUxOTU2XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzIwYmIyYTg2YWExYzQ0NmNiNDQ0ZjkxMGM2NmUwMTViKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2I2ZDQ3NjkwMjQzNjQzOTc4M2ZmYTgyM2QwMzY1MTM1ID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzc1ZDA4MTNiMTVkMjRmMzdiNDM0ZDZhN2FkNDVkYzljID0gJCgnPGRpdiBpZD0iaHRtbF83NWQwODEzYjE1ZDI0ZjM3YjQzNGQ2YTdhZDQ1ZGM5YyIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+MTgsIEJ1dHRlcy1Nb250bWFydHJlPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9iNmQ0NzY5MDI0MzY0Mzk3ODNmZmE4MjNkMDM2NTEzNS5zZXRDb250ZW50KGh0bWxfNzVkMDgxM2IxNWQyNGYzN2I0MzRkNmE3YWQ0NWRjOWMpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfODIxNjY4MGE0YWYyNDE2NTlmMGM4MjRiNjM2MWJhNjIuYmluZFBvcHVwKHBvcHVwX2I2ZDQ3NjkwMjQzNjQzOTc4M2ZmYTgyM2QwMzY1MTM1KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzU0NWE5ZDEyYjQ3ZTQ5YWM4N2E1YjI2ZjJmYzE1MjFjID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDguODg3MDc1OTk2NiwyLjM4NDgyMDk2MDE1XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogImJsdWUiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMzE4NmNjIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwXzIwYmIyYTg2YWExYzQ0NmNiNDQ0ZjkxMGM2NmUwMTViKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzZlNmU0MmY4N2E4NzRhNGI4ZTBkYjQ5MTkxNDZjOTQwID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzg4MjA4NmRhNzMyYTQwMDliYjk4NTc0YzQ1MjhjMTA2ID0gJCgnPGRpdiBpZD0iaHRtbF84ODIwODZkYTczMmE0MDA5YmI5ODU3NGM0NTI4YzEwNiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+MTksIEJ1dHRlcy1DaGF1bW9udDwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfNmU2ZTQyZjg3YTg3NGE0YjhlMGRiNDkxOTE0NmM5NDAuc2V0Q29udGVudChodG1sXzg4MjA4NmRhNzMyYTQwMDliYjk4NTc0YzQ1MjhjMTA2KTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzU0NWE5ZDEyYjQ3ZTQ5YWM4N2E1YjI2ZjJmYzE1MjFjLmJpbmRQb3B1cChwb3B1cF82ZTZlNDJmODdhODc0YTRiOGUwZGI0OTE5MTQ2Yzk0MCk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl84MDlmNGEyZWUzZTA0MDU4YmRiYjAyMTRmNmEzYTNiZSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQ4Ljg2MzQ2MDU3ODksMi40MDExODgxMjkyOF0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICJibHVlIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzMxODZjYyIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF8yMGJiMmE4NmFhMWM0NDZjYjQ0NGY5MTBjNjZlMDE1Yik7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF8wNTRiN2VjYmQ1YmU0MDMwODM2NmEwYjNkY2IxYTFmNCA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8zMzUwNThiYTNkZmM0NGVmOGE5ZWFlNmIyZTdkNDA4YiA9ICQoJzxkaXYgaWQ9Imh0bWxfMzM1MDU4YmEzZGZjNDRlZjhhOWVhZTZiMmU3ZDQwOGIiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPjIwLCBNw6luaWxtb250YW50PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8wNTRiN2VjYmQ1YmU0MDMwODM2NmEwYjNkY2IxYTFmNC5zZXRDb250ZW50KGh0bWxfMzM1MDU4YmEzZGZjNDRlZjhhOWVhZTZiMmU3ZDQwOGIpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfODA5ZjRhMmVlM2UwNDA1OGJkYmIwMjE0ZjZhM2EzYmUuYmluZFBvcHVwKHBvcHVwXzA1NGI3ZWNiZDViZTQwMzA4MzY2YTBiM2RjYjFhMWY0KTsKCiAgICAgICAgICAgIAogICAgICAgIAo8L3NjcmlwdD4=\" style=\"position:absolute;width:100%;height:100%;left:0;top:0;border:none !important;\" allowfullscreen webkitallowfullscreen mozallowfullscreen></iframe></div></div>"
],
"text/plain": [
"<folium.folium.Map at 0x7f750fc03f98>"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"map_paris = folium.Map(location=[latitude_par, longitude_par], zoom_start=12)\n",
"# add markers to the map\n",
"for lat, lng, arrondissement, neighborhood in zip(paris_data['Latitude'], paris_data['Longitude'], paris_data['Arrondissement'], paris_data['Neighborhood']):\n",
" label = \"{}, {}\".format(arrondissement,neighborhood)\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(map_paris) \n",
"map_paris.save('Paris.png')\n",
"map_paris"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Use Foursquare API to explore Neighbourhoods and segnment the data"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Foursquare credentials"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Your credentails:\n",
"CLIENT_ID: IZJNDNMGN2UG0QC4VTSCO0X3FIJCUWLEOMDME03AZXXKSFK1\n",
"CLIENT_SECRET:2VRK4XTUNZGWEC5FU3ITX45S3KRWYECKYHE10VK0EJLMJHGJ\n"
]
}
],
"source": [
"CLIENT_ID = 'IZJNDNMGN2UG0QC4VTSCO0X3FIJCUWLEOMDME03AZXXKSFK1' # your Foursquare ID\n",
"CLIENT_SECRET = '2VRK4XTUNZGWEC5FU3ITX45S3KRWYECKYHE10VK0EJLMJHGJ' # your Foursquare Secret\n",
"VERSION = '20180605' # Foursquare API version\n",
"print('Your credentails:')\n",
"print('CLIENT_ID: ' + CLIENT_ID)\n",
"print('CLIENT_SECRET:' + CLIENT_SECRET)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Function to get venues"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"def getNearbyVenues_paris(arrondissements, names, latitudes, longitudes, radius=750, limit=100):\n",
" \n",
" venues_list = []\n",
" for arrondissement, name, lat, lng in zip(arrondissements, names, latitudes, longitudes):\n",
" print(name)\n",
" \n",
" # create the API request URL\n",
" url = \"https://api.foursquare.com/v2/venues/explore?&client_id={}&client_secret={}&v={}&ll={},{}&radius={}&limit={}\".format(\n",
" CLIENT_ID, \n",
" CLIENT_SECRET, \n",
" VERSION, \n",
" lat, \n",
" lng, \n",
" radius, \n",
" limit)\n",
" \n",
" # make the GET request\n",
" results = requests.get(url).json()[\"response\"][\"groups\"][0][\"items\"]\n",
" \n",
" # return only relevant information for each nearby venue\n",
" venues_list.append([(\n",
" arrondissement,\n",
" name, \n",
" lat, \n",
" lng, \n",
" v[\"venue\"][\"name\"], \n",
" v[\"venue\"][\"location\"][\"lat\"], \n",
" v[\"venue\"][\"location\"][\"lng\"], \n",
" v[\"venue\"][\"categories\"][0][\"name\"]) for v in results])\n",
" \n",
" nearby_venues = pd.DataFrame([item for venue_list in venues_list for item in venue_list])\n",
" nearby_venues.columns = [\"Arrondissement\",\n",
" \"Neighborhood\", \n",
" \"Neighborhood Latitude\", \n",
" \"Neighborhood Longitude\", \n",
" \"Venue\", \n",
" \"Venue Latitude\", \n",
" \"Venue Longitude\", \n",
" \"Venue Category\"] \n",
" return(nearby_venues)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Louvre\n",
"Bourse\n",
"Temple\n",
"Hôtel-de-Ville\n",
"Panthéon\n",
"Luxembourg\n",
"Palais-Bourbon\n",
"Elysée\n",
"Opéra\n",
"Entrepôt\n",
"Popincourt\n",
"Reuilly\n",
"Gobelins\n",
"Observatoire\n",
"Vaugirard\n",
"Passy\n",
"Batignolles-Monceau\n",
"Buttes-Montmartre\n",
"Buttes-Chaumont\n",
"Ménilmontant\n"
]
}
],
"source": [
"paris_venues = getNearbyVenues_paris(arrondissements=paris_data[\"Arrondissement\"],\n",
" names = paris_data[\"Neighborhood\"],\n",
" latitudes = paris_data[\"Latitude\"],\n",
" longitudes = paris_data[\"Longitude\"]\n",
" )"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"(1815, 8)\n"
]
}
],
"source": [
"print(paris_venues.shape)"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"There are 222 unique categories.\n"
]
}
],
"source": [
"print(\"There are {} unique categories.\".format(len(paris_venues[\"Venue Category\"].unique())))"
]
},
{
"cell_type": "code",
"execution_count": 11,
"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>Arrondissement</th>\n",
" <th>Neighborhood</th>\n",
" <th>Neighborhood Latitude</th>\n",
" <th>Neighborhood Longitude</th>\n",
" <th>Venue</th>\n",
" <th>Venue Latitude</th>\n",
" <th>Venue Longitude</th>\n",
" <th>Venue Category</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>1</td>\n",
" <td>Louvre</td>\n",
" <td>48.862563</td>\n",
" <td>2.336443</td>\n",
" <td>Musée du Louvre</td>\n",
" <td>48.860847</td>\n",
" <td>2.336440</td>\n",
" <td>Art Museum</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>1</td>\n",
" <td>Louvre</td>\n",
" <td>48.862563</td>\n",
" <td>2.336443</td>\n",
" <td>Comédie-Française</td>\n",
" <td>48.863088</td>\n",
" <td>2.336612</td>\n",
" <td>Theater</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>1</td>\n",
" <td>Louvre</td>\n",
" <td>48.862563</td>\n",
" <td>2.336443</td>\n",
" <td>Palais Royal</td>\n",
" <td>48.863758</td>\n",
" <td>2.337121</td>\n",
" <td>Historic Site</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>1</td>\n",
" <td>Louvre</td>\n",
" <td>48.862563</td>\n",
" <td>2.336443</td>\n",
" <td>Place du Palais Royal</td>\n",
" <td>48.862523</td>\n",
" <td>2.336688</td>\n",
" <td>Plaza</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>1</td>\n",
" <td>Louvre</td>\n",
" <td>48.862563</td>\n",
" <td>2.336443</td>\n",
" <td>La Clef Louvre Paris</td>\n",
" <td>48.863977</td>\n",
" <td>2.336140</td>\n",
" <td>Hotel</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Arrondissement Neighborhood Neighborhood Latitude Neighborhood Longitude \\\n",
"0 1 Louvre 48.862563 2.336443 \n",
"1 1 Louvre 48.862563 2.336443 \n",
"2 1 Louvre 48.862563 2.336443 \n",
"3 1 Louvre 48.862563 2.336443 \n",
"4 1 Louvre 48.862563 2.336443 \n",
"\n",
" Venue Venue Latitude Venue Longitude Venue Category \n",
"0 Musée du Louvre 48.860847 2.336440 Art Museum \n",
"1 Comédie-Française 48.863088 2.336612 Theater \n",
"2 Palais Royal 48.863758 2.337121 Historic Site \n",
"3 Place du Palais Royal 48.862523 2.336688 Plaza \n",
"4 La Clef Louvre Paris   48.863977 2.336140 Hotel "
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"paris_venues.head()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Use Onehot encoding to explore Neighbourhoods"
]
},
{
"cell_type": "code",
"execution_count": 12,
"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>Arrondissement</th>\n",
" <th>Neighborhood</th>\n",
" <th>Afghan Restaurant</th>\n",
" <th>African Restaurant</th>\n",
" <th>American Restaurant</th>\n",
" <th>Antique Shop</th>\n",
" <th>Arepa Restaurant</th>\n",
" <th>Argentinian Restaurant</th>\n",
" <th>Art Gallery</th>\n",
" <th>Art Museum</th>\n",
" <th>...</th>\n",
" <th>Udon Restaurant</th>\n",
" <th>Vegetarian / Vegan Restaurant</th>\n",
" <th>Venezuelan Restaurant</th>\n",
" <th>Video Game Store</th>\n",
" <th>Vietnamese Restaurant</th>\n",
" <th>Wine Bar</th>\n",
" <th>Wine Shop</th>\n",
" <th>Women's Store</th>\n",
" <th>Yoga Studio</th>\n",
" <th>Zoo</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>1</td>\n",
" <td>Louvre</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</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>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>1</td>\n",
" <td>Louvre</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</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>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>1</td>\n",
" <td>Louvre</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</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>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>1</td>\n",
" <td>Louvre</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</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>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>1</td>\n",
" <td>Louvre</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</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>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>5 rows × 224 columns</p>\n",
"</div>"
],
"text/plain": [
" Arrondissement Neighborhood Afghan Restaurant African Restaurant \\\n",
"0 1 Louvre 0 0 \n",
"1 1 Louvre 0 0 \n",
"2 1 Louvre 0 0 \n",
"3 1 Louvre 0 0 \n",
"4 1 Louvre 0 0 \n",
"\n",
" American Restaurant Antique Shop Arepa Restaurant \\\n",
"0 0 0 0 \n",
"1 0 0 0 \n",
"2 0 0 0 \n",
"3 0 0 0 \n",
"4 0 0 0 \n",
"\n",
" Argentinian Restaurant Art Gallery Art Museum ... Udon Restaurant \\\n",
"0 0 0 1 ... 0 \n",
"1 0 0 0 ... 0 \n",
"2 0 0 0 ... 0 \n",
"3 0 0 0 ... 0 \n",
"4 0 0 0 ... 0 \n",
"\n",
" Vegetarian / Vegan Restaurant Venezuelan Restaurant Video Game Store \\\n",
"0 0 0 0 \n",
"1 0 0 0 \n",
"2 0 0 0 \n",
"3 0 0 0 \n",
"4 0 0 0 \n",
"\n",
" Vietnamese Restaurant Wine Bar Wine Shop Women's Store Yoga Studio Zoo \n",
"0 0 0 0 0 0 0 \n",
"1 0 0 0 0 0 0 \n",
"2 0 0 0 0 0 0 \n",
"3 0 0 0 0 0 0 \n",
"4 0 0 0 0 0 0 \n",
"\n",
"[5 rows x 224 columns]"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"paris_onehot = pd.get_dummies(paris_venues[[\"Venue Category\"]], prefix=\"\", prefix_sep=\"\")\n",
"# add arrondissement and neighborhood column back to dataframe\n",
"paris_onehot[\"Arrondissement\"] = paris_venues[\"Arrondissement\"] \n",
"paris_onehot[\"Neighborhood\"] = paris_venues[\"Neighborhood\"] \n",
"# move arrondissement and neighborhood columns to the first columns\n",
"fixed_columns = [paris_onehot.columns[-2], paris_onehot.columns[-1]] + list(paris_onehot.columns[:-2])\n",
"paris_onehot = paris_onehot[fixed_columns]\n",
"paris_onehot.head()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Group by neighborhood and by the mean frequency for each category"
]
},
{
"cell_type": "code",
"execution_count": 13,
"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>Arrondissement</th>\n",
" <th>Afghan Restaurant</th>\n",
" <th>African Restaurant</th>\n",
" <th>American Restaurant</th>\n",
" <th>Antique Shop</th>\n",
" <th>Arepa Restaurant</th>\n",
" <th>Argentinian Restaurant</th>\n",
" <th>Art Gallery</th>\n",
" <th>Art Museum</th>\n",
" <th>...</th>\n",
" <th>Udon Restaurant</th>\n",
" <th>Vegetarian / Vegan Restaurant</th>\n",
" <th>Venezuelan Restaurant</th>\n",
" <th>Video Game Store</th>\n",
" <th>Vietnamese Restaurant</th>\n",
" <th>Wine Bar</th>\n",
" <th>Wine Shop</th>\n",
" <th>Women's Store</th>\n",
" <th>Yoga Studio</th>\n",
" <th>Zoo</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Batignolles-Monceau</td>\n",
" <td>17</td>\n",
" <td>0.0</td>\n",
" <td>0.00</td>\n",
" <td>0.010417</td>\n",
" <td>0.0</td>\n",
" <td>0.00</td>\n",
" <td>0.00</td>\n",
" <td>0.00</td>\n",
" <td>0.00</td>\n",
" <td>...</td>\n",
" <td>0.0</td>\n",
" <td>0.00</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.00</td>\n",
" <td>0.00</td>\n",
" <td>0.00</td>\n",
" <td>0.00</td>\n",
" <td>0.010417</td>\n",
" <td>0.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>Bourse</td>\n",
" <td>2</td>\n",
" <td>0.0</td>\n",
" <td>0.00</td>\n",
" <td>0.010000</td>\n",
" <td>0.0</td>\n",
" <td>0.00</td>\n",
" <td>0.00</td>\n",
" <td>0.00</td>\n",
" <td>0.00</td>\n",
" <td>...</td>\n",
" <td>0.0</td>\n",
" <td>0.00</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.00</td>\n",
" <td>0.05</td>\n",
" <td>0.01</td>\n",
" <td>0.01</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>Buttes-Chaumont</td>\n",
" <td>19</td>\n",
" <td>0.0</td>\n",
" <td>0.00</td>\n",
" <td>0.010000</td>\n",
" <td>0.0</td>\n",
" <td>0.00</td>\n",
" <td>0.00</td>\n",
" <td>0.00</td>\n",
" <td>0.00</td>\n",
" <td>...</td>\n",
" <td>0.0</td>\n",
" <td>0.00</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.01</td>\n",
" <td>0.00</td>\n",
" <td>0.00</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>Buttes-Montmartre</td>\n",
" <td>18</td>\n",
" <td>0.0</td>\n",
" <td>0.01</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.01</td>\n",
" <td>0.01</td>\n",
" <td>0.02</td>\n",
" <td>0.00</td>\n",
" <td>...</td>\n",
" <td>0.0</td>\n",
" <td>0.02</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.02</td>\n",
" <td>0.02</td>\n",
" <td>0.00</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>Elysée</td>\n",
" <td>8</td>\n",
" <td>0.0</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" <td>0.00</td>\n",
" <td>0.00</td>\n",
" <td>0.04</td>\n",
" <td>0.01</td>\n",
" <td>...</td>\n",
" <td>0.0</td>\n",
" <td>0.00</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.00</td>\n",
" <td>0.00</td>\n",
" <td>0.00</td>\n",
" <td>0.00</td>\n",
" <td>0.000000</td>\n",
" <td>0.0</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>5 rows × 224 columns</p>\n",
"</div>"
],
"text/plain": [
" Neighborhood Arrondissement Afghan Restaurant African Restaurant \\\n",
"0 Batignolles-Monceau 17 0.0 0.00 \n",
"1 Bourse 2 0.0 0.00 \n",
"2 Buttes-Chaumont 19 0.0 0.00 \n",
"3 Buttes-Montmartre 18 0.0 0.01 \n",
"4 Elysée 8 0.0 0.00 \n",
"\n",
" American Restaurant Antique Shop Arepa Restaurant \\\n",
"0 0.010417 0.0 0.00 \n",
"1 0.010000 0.0 0.00 \n",
"2 0.010000 0.0 0.00 \n",
"3 0.000000 0.0 0.01 \n",
"4 0.000000 0.0 0.00 \n",
"\n",
" Argentinian Restaurant Art Gallery Art Museum ... Udon Restaurant \\\n",
"0 0.00 0.00 0.00 ... 0.0 \n",
"1 0.00 0.00 0.00 ... 0.0 \n",
"2 0.00 0.00 0.00 ... 0.0 \n",
"3 0.01 0.02 0.00 ... 0.0 \n",
"4 0.00 0.04 0.01 ... 0.0 \n",
"\n",
" Vegetarian / Vegan Restaurant Venezuelan Restaurant Video Game Store \\\n",
"0 0.00 0.0 0.0 \n",
"1 0.00 0.0 0.0 \n",
"2 0.00 0.0 0.0 \n",
"3 0.02 0.0 0.0 \n",
"4 0.00 0.0 0.0 \n",
"\n",
" Vietnamese Restaurant Wine Bar Wine Shop Women's Store Yoga Studio Zoo \n",
"0 0.00 0.00 0.00 0.00 0.010417 0.0 \n",
"1 0.00 0.05 0.01 0.01 0.000000 0.0 \n",
"2 0.01 0.00 0.00 0.00 0.000000 0.0 \n",
"3 0.02 0.02 0.00 0.00 0.000000 0.0 \n",
"4 0.00 0.00 0.00 0.00 0.000000 0.0 \n",
"\n",
"[5 rows x 224 columns]"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"paris_grouped = paris_onehot.groupby(\"Neighborhood\").mean().reset_index()\n",
"paris_grouped.head()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Top 5 most common categories of venues for each neighborhood "
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"----Batignolles-Monceau----\n",
" venue freq\n",
"0 Italian Restaurant 0.14\n",
"1 French Restaurant 0.14\n",
"2 Hotel 0.12\n",
"3 Japanese Restaurant 0.05\n",
"4 Bakery 0.05\n",
"\n",
"\n",
"----Bourse----\n",
" venue freq\n",
"0 French Restaurant 0.15\n",
"1 Bistro 0.06\n",
"2 Cocktail Bar 0.05\n",
"3 Wine Bar 0.05\n",
"4 Italian Restaurant 0.04\n",
"\n",
"\n",
"----Buttes-Chaumont----\n",
" venue freq\n",
"0 Bar 0.13\n",
"1 French Restaurant 0.08\n",
"2 Hotel 0.05\n",
"3 Pizza Place 0.05\n",
"4 Supermarket 0.04\n",
"\n",
"\n",
"----Buttes-Montmartre----\n",
" venue freq\n",
"0 French Restaurant 0.20\n",
"1 Bar 0.15\n",
"2 Pizza Place 0.06\n",
"3 Italian Restaurant 0.05\n",
"4 Bistro 0.05\n",
"\n",
"\n",
"----Elysée----\n",
" venue freq\n",
"0 French Restaurant 0.17\n",
"1 Hotel 0.17\n",
"2 Art Gallery 0.04\n",
"3 Bakery 0.04\n",
"4 Italian Restaurant 0.04\n",
"\n",
"\n",
"----Entrepôt----\n",
" venue freq\n",
"0 French Restaurant 0.08\n",
"1 Coffee Shop 0.08\n",
"2 Bistro 0.06\n",
"3 Pizza Place 0.05\n",
"4 Italian Restaurant 0.04\n",
"\n",
"\n",
"----Gobelins----\n",
" venue freq\n",
"0 Vietnamese Restaurant 0.18\n",
"1 Thai Restaurant 0.11\n",
"2 Asian Restaurant 0.11\n",
"3 Chinese Restaurant 0.07\n",
"4 French Restaurant 0.07\n",
"\n",
"\n",
"----Hôtel-de-Ville----\n",
" venue freq\n",
"0 French Restaurant 0.15\n",
"1 Ice Cream Shop 0.06\n",
"2 Plaza 0.04\n",
"3 Pastry Shop 0.03\n",
"4 Bakery 0.03\n",
"\n",
"\n",
"----Louvre----\n",
" venue freq\n",
"0 French Restaurant 0.10\n",
"1 Plaza 0.07\n",
"2 Hotel 0.07\n",
"3 Japanese Restaurant 0.06\n",
"4 Café 0.06\n",
"\n",
"\n",
"----Luxembourg----\n",
" venue freq\n",
"0 French Restaurant 0.09\n",
"1 Hotel 0.06\n",
"2 Italian Restaurant 0.05\n",
"3 Bistro 0.04\n",
"4 Chocolate Shop 0.04\n",
"\n",
"\n",
"----Ménilmontant----\n",
" venue freq\n",
"0 French Restaurant 0.14\n",
"1 Bar 0.09\n",
"2 Bakery 0.07\n",
"3 Bistro 0.06\n",
"4 Plaza 0.06\n",
"\n",
"\n",
"----Observatoire----\n",
" venue freq\n",
"0 French Restaurant 0.16\n",
"1 Hotel 0.10\n",
"2 Italian Restaurant 0.07\n",
"3 Café 0.04\n",
"4 Bistro 0.04\n",
"\n",
"\n",
"----Opéra----\n",
" venue freq\n",
"0 French Restaurant 0.17\n",
"1 Hotel 0.10\n",
"2 Cocktail Bar 0.06\n",
"3 Italian Restaurant 0.05\n",
"4 Bistro 0.04\n",
"\n",
"\n",
"----Palais-Bourbon----\n",
" venue freq\n",
"0 French Restaurant 0.28\n",
"1 Hotel 0.14\n",
"2 Plaza 0.06\n",
"3 Italian Restaurant 0.04\n",
"4 Cocktail Bar 0.03\n",
"\n",
"\n",
"----Panthéon----\n",
" venue freq\n",
"0 French Restaurant 0.18\n",
"1 Bar 0.06\n",
"2 Bakery 0.04\n",
"3 Hotel 0.04\n",
"4 Café 0.04\n",
"\n",
"\n",
"----Passy----\n",
" venue freq\n",
"0 Plaza 0.12\n",
"1 Garden 0.08\n",
"2 Lake 0.08\n",
"3 French Restaurant 0.08\n",
"4 Pool 0.08\n",
"\n",
"\n",
"----Popincourt----\n",
" venue freq\n",
"0 Bar 0.08\n",
"1 French Restaurant 0.08\n",
"2 Bistro 0.06\n",
"3 Cocktail Bar 0.06\n",
"4 Italian Restaurant 0.04\n",
"\n",
"\n",
"----Reuilly----\n",
" venue freq\n",
"0 Lake 0.22\n",
"1 Zoo 0.11\n",
"2 Bus Stop 0.11\n",
"3 Monument / Landmark 0.11\n",
"4 French Restaurant 0.11\n",
"\n",
"\n",
"----Temple----\n",
" venue freq\n",
"0 French Restaurant 0.07\n",
"1 Coffee Shop 0.05\n",
"2 Art Gallery 0.05\n",
"3 Italian Restaurant 0.04\n",
"4 Wine Bar 0.04\n",
"\n",
"\n",
"----Vaugirard----\n",
" venue freq\n",
"0 French Restaurant 0.18\n",
"1 Hotel 0.09\n",
"2 Italian Restaurant 0.05\n",
"3 Coffee Shop 0.05\n",
"4 Bistro 0.04\n",
"\n",
"\n"
]
}
],
"source": [
"num_top_venues = 5\n",
"for hood in paris_grouped[\"Neighborhood\"]:\n",
" print(\"----\"+hood+\"----\")\n",
" temp = paris_grouped[paris_grouped[\"Neighborhood\"]==hood].T.reset_index()\n",
" temp.columns = [\"venue\",\"freq\"]\n",
" temp = temp.iloc[2:]\n",
" temp[\"freq\"] = temp[\"freq\"].astype(float)\n",
" temp = temp.round({\"freq\": 2})\n",
" print(temp.sort_values(\"freq\", ascending=False).reset_index(drop=True).head(num_top_venues))\n",
" print(\"\\n\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- Considering that Paris is a touristic city, Hotels, restaurants, Coffee shops, Bakery and Bars dominates most neighbourhoods.\n",
"- In Reuilly neigbourhood, despite enormous touristic potentials, restaurants and hotels seem to absent. This could be a great investment opportunity for an investor\n",
"- Banks also seem not to be very common in most communities this also represent a great investment opportunities."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Define a function to sort the venues in descending order"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [],
"source": [
"def return_most_common_venues(row, num_top_venues):\n",
" row_categories = row.iloc[1:]\n",
" row_categories_sorted = row_categories.sort_values(ascending=False)\n",
" return row_categories_sorted.index.values[0:num_top_venues]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# The top 10 venues for each neighborhood"
]
},
{
"cell_type": "code",
"execution_count": 16,
"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>Arrondissement</th>\n",
" <th>Neighborhood</th>\n",
" <th>1st Most Common Venue</th>\n",
" <th>2nd Most Common Venue</th>\n",
" <th>3rd Most Common Venue</th>\n",
" <th>4th Most Common Venue</th>\n",
" <th>5th Most Common Venue</th>\n",
" <th>6th Most Common Venue</th>\n",
" <th>7th Most Common Venue</th>\n",
" <th>8th Most Common Venue</th>\n",
" <th>9th Most Common Venue</th>\n",
" <th>10th Most Common Venue</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>17</td>\n",
" <td>Batignolles-Monceau</td>\n",
" <td>French Restaurant</td>\n",
" <td>Italian Restaurant</td>\n",
" <td>Hotel</td>\n",
" <td>Japanese Restaurant</td>\n",
" <td>Bakery</td>\n",
" <td>Restaurant</td>\n",
" <td>Café</td>\n",
" <td>Bistro</td>\n",
" <td>Plaza</td>\n",
" <td>Bar</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>2</td>\n",
" <td>Bourse</td>\n",
" <td>French Restaurant</td>\n",
" <td>Bistro</td>\n",
" <td>Wine Bar</td>\n",
" <td>Cocktail Bar</td>\n",
" <td>Italian Restaurant</td>\n",
" <td>Boutique</td>\n",
" <td>Japanese Restaurant</td>\n",
" <td>Bakery</td>\n",
" <td>Creperie</td>\n",
" <td>Hotel</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>19</td>\n",
" <td>Buttes-Chaumont</td>\n",
" <td>Bar</td>\n",
" <td>French Restaurant</td>\n",
" <td>Pizza Place</td>\n",
" <td>Hotel</td>\n",
" <td>Supermarket</td>\n",
" <td>Smoke Shop</td>\n",
" <td>Café</td>\n",
" <td>Bistro</td>\n",
" <td>Restaurant</td>\n",
" <td>Seafood Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>18</td>\n",
" <td>Buttes-Montmartre</td>\n",
" <td>French Restaurant</td>\n",
" <td>Bar</td>\n",
" <td>Pizza Place</td>\n",
" <td>Bistro</td>\n",
" <td>Italian Restaurant</td>\n",
" <td>Coffee Shop</td>\n",
" <td>Café</td>\n",
" <td>Art Gallery</td>\n",
" <td>Middle Eastern Restaurant</td>\n",
" <td>Convenience Store</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>8</td>\n",
" <td>Elysée</td>\n",
" <td>French Restaurant</td>\n",
" <td>Hotel</td>\n",
" <td>Art Gallery</td>\n",
" <td>Italian Restaurant</td>\n",
" <td>Bakery</td>\n",
" <td>Theater</td>\n",
" <td>Clothing Store</td>\n",
" <td>Japanese Restaurant</td>\n",
" <td>Thai Restaurant</td>\n",
" <td>Boutique</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>10</td>\n",
" <td>Entrepôt</td>\n",
" <td>French Restaurant</td>\n",
" <td>Coffee Shop</td>\n",
" <td>Bistro</td>\n",
" <td>Pizza Place</td>\n",
" <td>Japanese Restaurant</td>\n",
" <td>Italian Restaurant</td>\n",
" <td>Bakery</td>\n",
" <td>Breakfast Spot</td>\n",
" <td>Indian Restaurant</td>\n",
" <td>Cocktail Bar</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td>13</td>\n",
" <td>Gobelins</td>\n",
" <td>Vietnamese Restaurant</td>\n",
" <td>Thai Restaurant</td>\n",
" <td>Asian Restaurant</td>\n",
" <td>French Restaurant</td>\n",
" <td>Chinese Restaurant</td>\n",
" <td>Bakery</td>\n",
" <td>Hotel</td>\n",
" <td>Cantonese Restaurant</td>\n",
" <td>Japanese Restaurant</td>\n",
" <td>Cambodian Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7</th>\n",
" <td>4</td>\n",
" <td>Hôtel-de-Ville</td>\n",
" <td>French Restaurant</td>\n",
" <td>Ice Cream Shop</td>\n",
" <td>Plaza</td>\n",
" <td>Wine Bar</td>\n",
" <td>Tapas Restaurant</td>\n",
" <td>Pastry Shop</td>\n",
" <td>Bakery</td>\n",
" <td>Cocktail Bar</td>\n",
" <td>Clothing Store</td>\n",
" <td>Gastropub</td>\n",
" </tr>\n",
" <tr>\n",
" <th>8</th>\n",
" <td>1</td>\n",
" <td>Louvre</td>\n",
" <td>French Restaurant</td>\n",
" <td>Plaza</td>\n",
" <td>Hotel</td>\n",
" <td>Café</td>\n",
" <td>Japanese Restaurant</td>\n",
" <td>Exhibit</td>\n",
" <td>Historic Site</td>\n",
" <td>Udon Restaurant</td>\n",
" <td>Art Museum</td>\n",
" <td>Cosmetics Shop</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9</th>\n",
" <td>6</td>\n",
" <td>Luxembourg</td>\n",
" <td>French Restaurant</td>\n",
" <td>Hotel</td>\n",
" <td>Italian Restaurant</td>\n",
" <td>Wine Bar</td>\n",
" <td>Chocolate Shop</td>\n",
" <td>Bistro</td>\n",
" <td>Seafood Restaurant</td>\n",
" <td>Tea Room</td>\n",
" <td>Plaza</td>\n",
" <td>Pastry Shop</td>\n",
" </tr>\n",
" <tr>\n",
" <th>10</th>\n",
" <td>20</td>\n",
" <td>Ménilmontant</td>\n",
" <td>French Restaurant</td>\n",
" <td>Bar</td>\n",
" <td>Bakery</td>\n",
" <td>Plaza</td>\n",
" <td>Bistro</td>\n",
" <td>Italian Restaurant</td>\n",
" <td>Café</td>\n",
" <td>Park</td>\n",
" <td>Bookstore</td>\n",
" <td>Supermarket</td>\n",
" </tr>\n",
" <tr>\n",
" <th>11</th>\n",
" <td>14</td>\n",
" <td>Observatoire</td>\n",
" <td>French Restaurant</td>\n",
" <td>Hotel</td>\n",
" <td>Italian Restaurant</td>\n",
" <td>Bistro</td>\n",
" <td>Café</td>\n",
" <td>Bar</td>\n",
" <td>Vietnamese Restaurant</td>\n",
" <td>Plaza</td>\n",
" <td>Bakery</td>\n",
" <td>Pizza Place</td>\n",
" </tr>\n",
" <tr>\n",
" <th>12</th>\n",
" <td>9</td>\n",
" <td>Opéra</td>\n",
" <td>French Restaurant</td>\n",
" <td>Hotel</td>\n",
" <td>Cocktail Bar</td>\n",
" <td>Italian Restaurant</td>\n",
" <td>Bistro</td>\n",
" <td>Bar</td>\n",
" <td>Bakery</td>\n",
" <td>Wine Bar</td>\n",
" <td>Lounge</td>\n",
" <td>Pizza Place</td>\n",
" </tr>\n",
" <tr>\n",
" <th>13</th>\n",
" <td>7</td>\n",
" <td>Palais-Bourbon</td>\n",
" <td>French Restaurant</td>\n",
" <td>Hotel</td>\n",
" <td>Plaza</td>\n",
" <td>Italian Restaurant</td>\n",
" <td>Café</td>\n",
" <td>Cocktail Bar</td>\n",
" <td>History Museum</td>\n",
" <td>Historic Site</td>\n",
" <td>Ice Cream Shop</td>\n",
" <td>Bar</td>\n",
" </tr>\n",
" <tr>\n",
" <th>14</th>\n",
" <td>5</td>\n",
" <td>Panthéon</td>\n",
" <td>French Restaurant</td>\n",
" <td>Bar</td>\n",
" <td>Wine Bar</td>\n",
" <td>Café</td>\n",
" <td>Hotel</td>\n",
" <td>Bakery</td>\n",
" <td>Plaza</td>\n",
" <td>Coffee Shop</td>\n",
" <td>Greek Restaurant</td>\n",
" <td>Museum</td>\n",
" </tr>\n",
" <tr>\n",
" <th>15</th>\n",
" <td>16</td>\n",
" <td>Passy</td>\n",
" <td>Plaza</td>\n",
" <td>Lake</td>\n",
" <td>Pool</td>\n",
" <td>French Restaurant</td>\n",
" <td>Garden</td>\n",
" <td>Diner</td>\n",
" <td>Skate Park</td>\n",
" <td>Bus Station</td>\n",
" <td>Bus Stop</td>\n",
" <td>Cafeteria</td>\n",
" </tr>\n",
" <tr>\n",
" <th>16</th>\n",
" <td>11</td>\n",
" <td>Popincourt</td>\n",
" <td>Bar</td>\n",
" <td>French Restaurant</td>\n",
" <td>Cocktail Bar</td>\n",
" <td>Bistro</td>\n",
" <td>Pizza Place</td>\n",
" <td>Italian Restaurant</td>\n",
" <td>Restaurant</td>\n",
" <td>Vegetarian / Vegan Restaurant</td>\n",
" <td>Beer Bar</td>\n",
" <td>Wine Bar</td>\n",
" </tr>\n",
" <tr>\n",
" <th>17</th>\n",
" <td>12</td>\n",
" <td>Reuilly</td>\n",
" <td>Lake</td>\n",
" <td>Zoo</td>\n",
" <td>Diner</td>\n",
" <td>Bus Stop</td>\n",
" <td>Exhibit</td>\n",
" <td>French Restaurant</td>\n",
" <td>Monument / Landmark</td>\n",
" <td>Japanese Restaurant</td>\n",
" <td>Hot Dog Joint</td>\n",
" <td>Fast Food Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>18</th>\n",
" <td>3</td>\n",
" <td>Temple</td>\n",
" <td>French Restaurant</td>\n",
" <td>Art Gallery</td>\n",
" <td>Coffee Shop</td>\n",
" <td>Gourmet Shop</td>\n",
" <td>Wine Bar</td>\n",
" <td>Italian Restaurant</td>\n",
" <td>Chinese Restaurant</td>\n",
" <td>Moroccan Restaurant</td>\n",
" <td>Sandwich Place</td>\n",
" <td>Cocktail Bar</td>\n",
" </tr>\n",
" <tr>\n",
" <th>19</th>\n",
" <td>15</td>\n",
" <td>Vaugirard</td>\n",
" <td>French Restaurant</td>\n",
" <td>Hotel</td>\n",
" <td>Italian Restaurant</td>\n",
" <td>Coffee Shop</td>\n",
" <td>Bistro</td>\n",
" <td>Persian Restaurant</td>\n",
" <td>Lebanese Restaurant</td>\n",
" <td>Park</td>\n",
" <td>Restaurant</td>\n",
" <td>Japanese Restaurant</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Arrondissement Neighborhood 1st Most Common Venue \\\n",
"0 17 Batignolles-Monceau French Restaurant \n",
"1 2 Bourse French Restaurant \n",
"2 19 Buttes-Chaumont Bar \n",
"3 18 Buttes-Montmartre French Restaurant \n",
"4 8 Elysée French Restaurant \n",
"5 10 Entrepôt French Restaurant \n",
"6 13 Gobelins Vietnamese Restaurant \n",
"7 4 Hôtel-de-Ville French Restaurant \n",
"8 1 Louvre French Restaurant \n",
"9 6 Luxembourg French Restaurant \n",
"10 20 Ménilmontant French Restaurant \n",
"11 14 Observatoire French Restaurant \n",
"12 9 Opéra French Restaurant \n",
"13 7 Palais-Bourbon French Restaurant \n",
"14 5 Panthéon French Restaurant \n",
"15 16 Passy Plaza \n",
"16 11 Popincourt Bar \n",
"17 12 Reuilly Lake \n",
"18 3 Temple French Restaurant \n",
"19 15 Vaugirard French Restaurant \n",
"\n",
" 2nd Most Common Venue 3rd Most Common Venue 4th Most Common Venue \\\n",
"0 Italian Restaurant Hotel Japanese Restaurant \n",
"1 Bistro Wine Bar Cocktail Bar \n",
"2 French Restaurant Pizza Place Hotel \n",
"3 Bar Pizza Place Bistro \n",
"4 Hotel Art Gallery Italian Restaurant \n",
"5 Coffee Shop Bistro Pizza Place \n",
"6 Thai Restaurant Asian Restaurant French Restaurant \n",
"7 Ice Cream Shop Plaza Wine Bar \n",
"8 Plaza Hotel Café \n",
"9 Hotel Italian Restaurant Wine Bar \n",
"10 Bar Bakery Plaza \n",
"11 Hotel Italian Restaurant Bistro \n",
"12 Hotel Cocktail Bar Italian Restaurant \n",
"13 Hotel Plaza Italian Restaurant \n",
"14 Bar Wine Bar Café \n",
"15 Lake Pool French Restaurant \n",
"16 French Restaurant Cocktail Bar Bistro \n",
"17 Zoo Diner Bus Stop \n",
"18 Art Gallery Coffee Shop Gourmet Shop \n",
"19 Hotel Italian Restaurant Coffee Shop \n",
"\n",
" 5th Most Common Venue 6th Most Common Venue 7th Most Common Venue \\\n",
"0 Bakery Restaurant Café \n",
"1 Italian Restaurant Boutique Japanese Restaurant \n",
"2 Supermarket Smoke Shop Café \n",
"3 Italian Restaurant Coffee Shop Café \n",
"4 Bakery Theater Clothing Store \n",
"5 Japanese Restaurant Italian Restaurant Bakery \n",
"6 Chinese Restaurant Bakery Hotel \n",
"7 Tapas Restaurant Pastry Shop Bakery \n",
"8 Japanese Restaurant Exhibit Historic Site \n",
"9 Chocolate Shop Bistro Seafood Restaurant \n",
"10 Bistro Italian Restaurant Café \n",
"11 Café Bar Vietnamese Restaurant \n",
"12 Bistro Bar Bakery \n",
"13 Café Cocktail Bar History Museum \n",
"14 Hotel Bakery Plaza \n",
"15 Garden Diner Skate Park \n",
"16 Pizza Place Italian Restaurant Restaurant \n",
"17 Exhibit French Restaurant Monument / Landmark \n",
"18 Wine Bar Italian Restaurant Chinese Restaurant \n",
"19 Bistro Persian Restaurant Lebanese Restaurant \n",
"\n",
" 8th Most Common Venue 9th Most Common Venue \\\n",
"0 Bistro Plaza \n",
"1 Bakery Creperie \n",
"2 Bistro Restaurant \n",
"3 Art Gallery Middle Eastern Restaurant \n",
"4 Japanese Restaurant Thai Restaurant \n",
"5 Breakfast Spot Indian Restaurant \n",
"6 Cantonese Restaurant Japanese Restaurant \n",
"7 Cocktail Bar Clothing Store \n",
"8 Udon Restaurant Art Museum \n",
"9 Tea Room Plaza \n",
"10 Park Bookstore \n",
"11 Plaza Bakery \n",
"12 Wine Bar Lounge \n",
"13 Historic Site Ice Cream Shop \n",
"14 Coffee Shop Greek Restaurant \n",
"15 Bus Station Bus Stop \n",
"16 Vegetarian / Vegan Restaurant Beer Bar \n",
"17 Japanese Restaurant Hot Dog Joint \n",
"18 Moroccan Restaurant Sandwich Place \n",
"19 Park Restaurant \n",
"\n",
" 10th Most Common Venue \n",
"0 Bar \n",
"1 Hotel \n",
"2 Seafood Restaurant \n",
"3 Convenience Store \n",
"4 Boutique \n",
"5 Cocktail Bar \n",
"6 Cambodian Restaurant \n",
"7 Gastropub \n",
"8 Cosmetics Shop \n",
"9 Pastry Shop \n",
"10 Supermarket \n",
"11 Pizza Place \n",
"12 Pizza Place \n",
"13 Bar \n",
"14 Museum \n",
"15 Cafeteria \n",
"16 Wine Bar \n",
"17 Fast Food Restaurant \n",
"18 Cocktail Bar \n",
"19 Japanese Restaurant "
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"num_top_venues = 10\n",
"indicators = [\"st\", \"nd\", \"rd\"]\n",
"# create columns according to number of top venues\n",
"columns = [\"Arrondissement\", \"Neighborhood\"]\n",
"for ind in np.arange(num_top_venues):\n",
" try:\n",
" columns.append(\"{}{} Most Common Venue\".format(ind+1, indicators[ind]))\n",
" except:\n",
" columns.append(\"{}th Most Common Venue\".format(ind+1))\n",
"# create a new dataframe\n",
"paris_neighborhoods_venues_sorted = pd.DataFrame(columns=columns)\n",
"paris_neighborhoods_venues_sorted[[ \"Arrondissement\",\"Neighborhood\"]] = paris_grouped[[\"Arrondissement\",\"Neighborhood\"]]\n",
"for ind in np.arange(paris_grouped.shape[0]):\n",
" paris_neighborhoods_venues_sorted.iloc[ind, 2:] = return_most_common_venues(paris_grouped.iloc[ind, 1:], num_top_venues)\n",
"paris_neighborhoods_venues_sorted"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Cluster the venues and visualize them on a map"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Create the metric (same squared distances) to identify the best k"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"columns = [\"Neighborhood\", \"Arrondissement\"]\n",
"paris_grouped_clustering = paris_grouped.drop(columns, axis = 1)\n",
"Sum_of_squared_distances = []\n",
"ks = range(1,11)\n",
"for k in ks:\n",
" kmeans = KMeans(n_clusters=k, random_state=0).fit(paris_grouped_clustering)\n",
" Sum_of_squared_distances.append(kmeans.inertia_)\n",
"\n",
"# Plot of sum of squared distances\n",
"plt.plot(ks, Sum_of_squared_distances, \"bx-\")\n",
"plt.xlabel(\"k number of clusters\")\n",
"plt.ylabel(\"Sum_of_squared_distances\")\n",
"plt.title(\"Elbow method for optimal k\")\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"According to the figure above, the correct value for k could be 4 or 5. Here, we choose to cluster the data points using k=5."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Cluster the venues of Paris into 5 clusters"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([3, 1, 1, 1, 3, 1, 4, 1, 1, 1], dtype=int32)"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"kclusters = 5\n",
"# run k-means clustering\n",
"kmeans = KMeans(n_clusters=kclusters, random_state=0).fit(paris_grouped_clustering)\n",
"# check cluster labels generated for each row in the dataframe\n",
"kmeans.labels_[0:10]"
]
},
{
"cell_type": "code",
"execution_count": 19,
"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>Arrondissement</th>\n",
" <th>Neighborhood</th>\n",
" <th>Latitude</th>\n",
" <th>Longitude</th>\n",
" <th>Cluster Labels</th>\n",
" <th>1st Most Common Venue</th>\n",
" <th>2nd Most Common Venue</th>\n",
" <th>3rd Most Common Venue</th>\n",
" <th>4th Most Common Venue</th>\n",
" <th>5th Most Common Venue</th>\n",
" <th>6th Most Common Venue</th>\n",
" <th>7th Most Common Venue</th>\n",
" <th>8th Most Common Venue</th>\n",
" <th>9th Most Common Venue</th>\n",
" <th>10th Most Common Venue</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>1</td>\n",
" <td>Louvre</td>\n",
" <td>48.862563</td>\n",
" <td>2.336443</td>\n",
" <td>3</td>\n",
" <td>French Restaurant</td>\n",
" <td>Plaza</td>\n",
" <td>Hotel</td>\n",
" <td>Café</td>\n",
" <td>Japanese Restaurant</td>\n",
" <td>Exhibit</td>\n",
" <td>Historic Site</td>\n",
" <td>Udon Restaurant</td>\n",
" <td>Art Museum</td>\n",
" <td>Cosmetics Shop</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>2</td>\n",
" <td>Bourse</td>\n",
" <td>48.868279</td>\n",
" <td>2.342803</td>\n",
" <td>1</td>\n",
" <td>French Restaurant</td>\n",
" <td>Bistro</td>\n",
" <td>Wine Bar</td>\n",
" <td>Cocktail Bar</td>\n",
" <td>Italian Restaurant</td>\n",
" <td>Boutique</td>\n",
" <td>Japanese Restaurant</td>\n",
" <td>Bakery</td>\n",
" <td>Creperie</td>\n",
" <td>Hotel</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>3</td>\n",
" <td>Temple</td>\n",
" <td>48.862872</td>\n",
" <td>2.360001</td>\n",
" <td>1</td>\n",
" <td>French Restaurant</td>\n",
" <td>Art Gallery</td>\n",
" <td>Coffee Shop</td>\n",
" <td>Gourmet Shop</td>\n",
" <td>Wine Bar</td>\n",
" <td>Italian Restaurant</td>\n",
" <td>Chinese Restaurant</td>\n",
" <td>Moroccan Restaurant</td>\n",
" <td>Sandwich Place</td>\n",
" <td>Cocktail Bar</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>4</td>\n",
" <td>Hôtel-de-Ville</td>\n",
" <td>48.854341</td>\n",
" <td>2.357630</td>\n",
" <td>1</td>\n",
" <td>French Restaurant</td>\n",
" <td>Ice Cream Shop</td>\n",
" <td>Plaza</td>\n",
" <td>Wine Bar</td>\n",
" <td>Tapas Restaurant</td>\n",
" <td>Pastry Shop</td>\n",
" <td>Bakery</td>\n",
" <td>Cocktail Bar</td>\n",
" <td>Clothing Store</td>\n",
" <td>Gastropub</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>5</td>\n",
" <td>Panthéon</td>\n",
" <td>48.844443</td>\n",
" <td>2.350715</td>\n",
" <td>3</td>\n",
" <td>French Restaurant</td>\n",
" <td>Bar</td>\n",
" <td>Wine Bar</td>\n",
" <td>Café</td>\n",
" <td>Hotel</td>\n",
" <td>Bakery</td>\n",
" <td>Plaza</td>\n",
" <td>Coffee Shop</td>\n",
" <td>Greek Restaurant</td>\n",
" <td>Museum</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>6</td>\n",
" <td>Luxembourg</td>\n",
" <td>48.849130</td>\n",
" <td>2.332898</td>\n",
" <td>1</td>\n",
" <td>French Restaurant</td>\n",
" <td>Hotel</td>\n",
" <td>Italian Restaurant</td>\n",
" <td>Wine Bar</td>\n",
" <td>Chocolate Shop</td>\n",
" <td>Bistro</td>\n",
" <td>Seafood Restaurant</td>\n",
" <td>Tea Room</td>\n",
" <td>Plaza</td>\n",
" <td>Pastry Shop</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td>7</td>\n",
" <td>Palais-Bourbon</td>\n",
" <td>48.856174</td>\n",
" <td>2.312188</td>\n",
" <td>4</td>\n",
" <td>French Restaurant</td>\n",
" <td>Hotel</td>\n",
" <td>Plaza</td>\n",
" <td>Italian Restaurant</td>\n",
" <td>Café</td>\n",
" <td>Cocktail Bar</td>\n",
" <td>History Museum</td>\n",
" <td>Historic Site</td>\n",
" <td>Ice Cream Shop</td>\n",
" <td>Bar</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7</th>\n",
" <td>8</td>\n",
" <td>Elysée</td>\n",
" <td>48.872721</td>\n",
" <td>2.312554</td>\n",
" <td>1</td>\n",
" <td>French Restaurant</td>\n",
" <td>Hotel</td>\n",
" <td>Art Gallery</td>\n",
" <td>Italian Restaurant</td>\n",
" <td>Bakery</td>\n",
" <td>Theater</td>\n",
" <td>Clothing Store</td>\n",
" <td>Japanese Restaurant</td>\n",
" <td>Thai Restaurant</td>\n",
" <td>Boutique</td>\n",
" </tr>\n",
" <tr>\n",
" <th>8</th>\n",
" <td>9</td>\n",
" <td>Opéra</td>\n",
" <td>48.877164</td>\n",
" <td>2.337458</td>\n",
" <td>1</td>\n",
" <td>French Restaurant</td>\n",
" <td>Hotel</td>\n",
" <td>Cocktail Bar</td>\n",
" <td>Italian Restaurant</td>\n",
" <td>Bistro</td>\n",
" <td>Bar</td>\n",
" <td>Bakery</td>\n",
" <td>Wine Bar</td>\n",
" <td>Lounge</td>\n",
" <td>Pizza Place</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9</th>\n",
" <td>10</td>\n",
" <td>Entrepôt</td>\n",
" <td>48.876130</td>\n",
" <td>2.360728</td>\n",
" <td>1</td>\n",
" <td>French Restaurant</td>\n",
" <td>Coffee Shop</td>\n",
" <td>Bistro</td>\n",
" <td>Pizza Place</td>\n",
" <td>Japanese Restaurant</td>\n",
" <td>Italian Restaurant</td>\n",
" <td>Bakery</td>\n",
" <td>Breakfast Spot</td>\n",
" <td>Indian Restaurant</td>\n",
" <td>Cocktail Bar</td>\n",
" </tr>\n",
" <tr>\n",
" <th>10</th>\n",
" <td>11</td>\n",
" <td>Popincourt</td>\n",
" <td>48.859059</td>\n",
" <td>2.380058</td>\n",
" <td>1</td>\n",
" <td>Bar</td>\n",
" <td>French Restaurant</td>\n",
" <td>Cocktail Bar</td>\n",
" <td>Bistro</td>\n",
" <td>Pizza Place</td>\n",
" <td>Italian Restaurant</td>\n",
" <td>Restaurant</td>\n",
" <td>Vegetarian / Vegan Restaurant</td>\n",
" <td>Beer Bar</td>\n",
" <td>Wine Bar</td>\n",
" </tr>\n",
" <tr>\n",
" <th>11</th>\n",
" <td>12</td>\n",
" <td>Reuilly</td>\n",
" <td>48.834974</td>\n",
" <td>2.421325</td>\n",
" <td>3</td>\n",
" <td>Lake</td>\n",
" <td>Zoo</td>\n",
" <td>Diner</td>\n",
" <td>Bus Stop</td>\n",
" <td>Exhibit</td>\n",
" <td>French Restaurant</td>\n",
" <td>Monument / Landmark</td>\n",
" <td>Japanese Restaurant</td>\n",
" <td>Hot Dog Joint</td>\n",
" <td>Fast Food Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>12</th>\n",
" <td>13</td>\n",
" <td>Gobelins</td>\n",
" <td>48.828388</td>\n",
" <td>2.362272</td>\n",
" <td>3</td>\n",
" <td>Vietnamese Restaurant</td>\n",
" <td>Thai Restaurant</td>\n",
" <td>Asian Restaurant</td>\n",
" <td>French Restaurant</td>\n",
" <td>Chinese Restaurant</td>\n",
" <td>Bakery</td>\n",
" <td>Hotel</td>\n",
" <td>Cantonese Restaurant</td>\n",
" <td>Japanese Restaurant</td>\n",
" <td>Cambodian Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>13</th>\n",
" <td>14</td>\n",
" <td>Observatoire</td>\n",
" <td>48.829245</td>\n",
" <td>2.326542</td>\n",
" <td>3</td>\n",
" <td>French Restaurant</td>\n",
" <td>Hotel</td>\n",
" <td>Italian Restaurant</td>\n",
" <td>Bistro</td>\n",
" <td>Café</td>\n",
" <td>Bar</td>\n",
" <td>Vietnamese Restaurant</td>\n",
" <td>Plaza</td>\n",
" <td>Bakery</td>\n",
" <td>Pizza Place</td>\n",
" </tr>\n",
" <tr>\n",
" <th>14</th>\n",
" <td>15</td>\n",
" <td>Vaugirard</td>\n",
" <td>48.840085</td>\n",
" <td>2.292826</td>\n",
" <td>1</td>\n",
" <td>French Restaurant</td>\n",
" <td>Hotel</td>\n",
" <td>Italian Restaurant</td>\n",
" <td>Coffee Shop</td>\n",
" <td>Bistro</td>\n",
" <td>Persian Restaurant</td>\n",
" <td>Lebanese Restaurant</td>\n",
" <td>Park</td>\n",
" <td>Restaurant</td>\n",
" <td>Japanese Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>15</th>\n",
" <td>16</td>\n",
" <td>Passy</td>\n",
" <td>48.860392</td>\n",
" <td>2.261971</td>\n",
" <td>2</td>\n",
" <td>Plaza</td>\n",
" <td>Lake</td>\n",
" <td>Pool</td>\n",
" <td>French Restaurant</td>\n",
" <td>Garden</td>\n",
" <td>Diner</td>\n",
" <td>Skate Park</td>\n",
" <td>Bus Station</td>\n",
" <td>Bus Stop</td>\n",
" <td>Cafeteria</td>\n",
" </tr>\n",
" <tr>\n",
" <th>16</th>\n",
" <td>17</td>\n",
" <td>Batignolles-Monceau</td>\n",
" <td>48.887327</td>\n",
" <td>2.306777</td>\n",
" <td>1</td>\n",
" <td>French Restaurant</td>\n",
" <td>Italian Restaurant</td>\n",
" <td>Hotel</td>\n",
" <td>Japanese Restaurant</td>\n",
" <td>Bakery</td>\n",
" <td>Restaurant</td>\n",
" <td>Café</td>\n",
" <td>Bistro</td>\n",
" <td>Plaza</td>\n",
" <td>Bar</td>\n",
" </tr>\n",
" <tr>\n",
" <th>17</th>\n",
" <td>18</td>\n",
" <td>Buttes-Montmartre</td>\n",
" <td>48.892569</td>\n",
" <td>2.348161</td>\n",
" <td>0</td>\n",
" <td>French Restaurant</td>\n",
" <td>Bar</td>\n",
" <td>Pizza Place</td>\n",
" <td>Bistro</td>\n",
" <td>Italian Restaurant</td>\n",
" <td>Coffee Shop</td>\n",
" <td>Café</td>\n",
" <td>Art Gallery</td>\n",
" <td>Middle Eastern Restaurant</td>\n",
" <td>Convenience Store</td>\n",
" </tr>\n",
" <tr>\n",
" <th>18</th>\n",
" <td>19</td>\n",
" <td>Buttes-Chaumont</td>\n",
" <td>48.887076</td>\n",
" <td>2.384821</td>\n",
" <td>1</td>\n",
" <td>Bar</td>\n",
" <td>French Restaurant</td>\n",
" <td>Pizza Place</td>\n",
" <td>Hotel</td>\n",
" <td>Supermarket</td>\n",
" <td>Smoke Shop</td>\n",
" <td>Café</td>\n",
" <td>Bistro</td>\n",
" <td>Restaurant</td>\n",
" <td>Seafood Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>19</th>\n",
" <td>20</td>\n",
" <td>Ménilmontant</td>\n",
" <td>48.863461</td>\n",
" <td>2.401188</td>\n",
" <td>3</td>\n",
" <td>French Restaurant</td>\n",
" <td>Bar</td>\n",
" <td>Bakery</td>\n",
" <td>Plaza</td>\n",
" <td>Bistro</td>\n",
" <td>Italian Restaurant</td>\n",
" <td>Café</td>\n",
" <td>Park</td>\n",
" <td>Bookstore</td>\n",
" <td>Supermarket</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Arrondissement Neighborhood Latitude Longitude Cluster Labels \\\n",
"0 1 Louvre 48.862563 2.336443 3 \n",
"1 2 Bourse 48.868279 2.342803 1 \n",
"2 3 Temple 48.862872 2.360001 1 \n",
"3 4 Hôtel-de-Ville 48.854341 2.357630 1 \n",
"4 5 Panthéon 48.844443 2.350715 3 \n",
"5 6 Luxembourg 48.849130 2.332898 1 \n",
"6 7 Palais-Bourbon 48.856174 2.312188 4 \n",
"7 8 Elysée 48.872721 2.312554 1 \n",
"8 9 Opéra 48.877164 2.337458 1 \n",
"9 10 Entrepôt 48.876130 2.360728 1 \n",
"10 11 Popincourt 48.859059 2.380058 1 \n",
"11 12 Reuilly 48.834974 2.421325 3 \n",
"12 13 Gobelins 48.828388 2.362272 3 \n",
"13 14 Observatoire 48.829245 2.326542 3 \n",
"14 15 Vaugirard 48.840085 2.292826 1 \n",
"15 16 Passy 48.860392 2.261971 2 \n",
"16 17 Batignolles-Monceau 48.887327 2.306777 1 \n",
"17 18 Buttes-Montmartre 48.892569 2.348161 0 \n",
"18 19 Buttes-Chaumont 48.887076 2.384821 1 \n",
"19 20 Ménilmontant 48.863461 2.401188 3 \n",
"\n",
" 1st Most Common Venue 2nd Most Common Venue 3rd Most Common Venue \\\n",
"0 French Restaurant Plaza Hotel \n",
"1 French Restaurant Bistro Wine Bar \n",
"2 French Restaurant Art Gallery Coffee Shop \n",
"3 French Restaurant Ice Cream Shop Plaza \n",
"4 French Restaurant Bar Wine Bar \n",
"5 French Restaurant Hotel Italian Restaurant \n",
"6 French Restaurant Hotel Plaza \n",
"7 French Restaurant Hotel Art Gallery \n",
"8 French Restaurant Hotel Cocktail Bar \n",
"9 French Restaurant Coffee Shop Bistro \n",
"10 Bar French Restaurant Cocktail Bar \n",
"11 Lake Zoo Diner \n",
"12 Vietnamese Restaurant Thai Restaurant Asian Restaurant \n",
"13 French Restaurant Hotel Italian Restaurant \n",
"14 French Restaurant Hotel Italian Restaurant \n",
"15 Plaza Lake Pool \n",
"16 French Restaurant Italian Restaurant Hotel \n",
"17 French Restaurant Bar Pizza Place \n",
"18 Bar French Restaurant Pizza Place \n",
"19 French Restaurant Bar Bakery \n",
"\n",
" 4th Most Common Venue 5th Most Common Venue 6th Most Common Venue \\\n",
"0 Café Japanese Restaurant Exhibit \n",
"1 Cocktail Bar Italian Restaurant Boutique \n",
"2 Gourmet Shop Wine Bar Italian Restaurant \n",
"3 Wine Bar Tapas Restaurant Pastry Shop \n",
"4 Café Hotel Bakery \n",
"5 Wine Bar Chocolate Shop Bistro \n",
"6 Italian Restaurant Café Cocktail Bar \n",
"7 Italian Restaurant Bakery Theater \n",
"8 Italian Restaurant Bistro Bar \n",
"9 Pizza Place Japanese Restaurant Italian Restaurant \n",
"10 Bistro Pizza Place Italian Restaurant \n",
"11 Bus Stop Exhibit French Restaurant \n",
"12 French Restaurant Chinese Restaurant Bakery \n",
"13 Bistro Café Bar \n",
"14 Coffee Shop Bistro Persian Restaurant \n",
"15 French Restaurant Garden Diner \n",
"16 Japanese Restaurant Bakery Restaurant \n",
"17 Bistro Italian Restaurant Coffee Shop \n",
"18 Hotel Supermarket Smoke Shop \n",
"19 Plaza Bistro Italian Restaurant \n",
"\n",
" 7th Most Common Venue 8th Most Common Venue \\\n",
"0 Historic Site Udon Restaurant \n",
"1 Japanese Restaurant Bakery \n",
"2 Chinese Restaurant Moroccan Restaurant \n",
"3 Bakery Cocktail Bar \n",
"4 Plaza Coffee Shop \n",
"5 Seafood Restaurant Tea Room \n",
"6 History Museum Historic Site \n",
"7 Clothing Store Japanese Restaurant \n",
"8 Bakery Wine Bar \n",
"9 Bakery Breakfast Spot \n",
"10 Restaurant Vegetarian / Vegan Restaurant \n",
"11 Monument / Landmark Japanese Restaurant \n",
"12 Hotel Cantonese Restaurant \n",
"13 Vietnamese Restaurant Plaza \n",
"14 Lebanese Restaurant Park \n",
"15 Skate Park Bus Station \n",
"16 Café Bistro \n",
"17 Café Art Gallery \n",
"18 Café Bistro \n",
"19 Café Park \n",
"\n",
" 9th Most Common Venue 10th Most Common Venue \n",
"0 Art Museum Cosmetics Shop \n",
"1 Creperie Hotel \n",
"2 Sandwich Place Cocktail Bar \n",
"3 Clothing Store Gastropub \n",
"4 Greek Restaurant Museum \n",
"5 Plaza Pastry Shop \n",
"6 Ice Cream Shop Bar \n",
"7 Thai Restaurant Boutique \n",
"8 Lounge Pizza Place \n",
"9 Indian Restaurant Cocktail Bar \n",
"10 Beer Bar Wine Bar \n",
"11 Hot Dog Joint Fast Food Restaurant \n",
"12 Japanese Restaurant Cambodian Restaurant \n",
"13 Bakery Pizza Place \n",
"14 Restaurant Japanese Restaurant \n",
"15 Bus Stop Cafeteria \n",
"16 Plaza Bar \n",
"17 Middle Eastern Restaurant Convenience Store \n",
"18 Restaurant Seafood Restaurant \n",
"19 Bookstore Supermarket "
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"paris_merged = paris_data\n",
"# add clustering labels\n",
"paris_merged[\"Cluster Labels\"] = kmeans.labels_\n",
"paris_merged = pd.merge(paris_merged, paris_neighborhoods_venues_sorted, how = \"left\", left_on = [\"Arrondissement\",\"Neighborhood\"], right_on = [\"Arrondissement\",\"Neighborhood\"])\n",
"paris_merged"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Represent Clusters on a map"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div style=\"width:100%;\"><div style=\"position:relative;width:100%;height:0;padding-bottom:60%;\"><iframe src=\"data:text/html;charset=utf-8;base64,PCFET0NUWVBFIGh0bWw+CjxoZWFkPiAgICAKICAgIDxtZXRhIGh0dHAtZXF1aXY9ImNvbnRlbnQtdHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PVVURi04IiAvPgogICAgPHNjcmlwdD5MX1BSRUZFUl9DQU5WQVMgPSBmYWxzZTsgTF9OT19UT1VDSCA9IGZhbHNlOyBMX0RJU0FCTEVfM0QgPSBmYWxzZTs8L3NjcmlwdD4KICAgIDxzY3JpcHQgc3JjPSJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL2xlYWZsZXRAMS4yLjAvZGlzdC9sZWFmbGV0LmpzIj48L3NjcmlwdD4KICAgIDxzY3JpcHQgc3JjPSJodHRwczovL2FqYXguZ29vZ2xlYXBpcy5jb20vYWpheC9saWJzL2pxdWVyeS8xLjExLjEvanF1ZXJ5Lm1pbi5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IHNyYz0iaHR0cHM6Ly9tYXhjZG4uYm9vdHN0cmFwY2RuLmNvbS9ib290c3RyYXAvMy4yLjAvanMvYm9vdHN0cmFwLm1pbi5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IHNyYz0iaHR0cHM6Ly9jZG5qcy5jbG91ZGZsYXJlLmNvbS9hamF4L2xpYnMvTGVhZmxldC5hd2Vzb21lLW1hcmtlcnMvMi4wLjIvbGVhZmxldC5hd2Vzb21lLW1hcmtlcnMuanMiPjwvc2NyaXB0PgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL2xlYWZsZXRAMS4yLjAvZGlzdC9sZWFmbGV0LmNzcyIvPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL21heGNkbi5ib290c3RyYXBjZG4uY29tL2Jvb3RzdHJhcC8zLjIuMC9jc3MvYm9vdHN0cmFwLm1pbi5jc3MiLz4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cHM6Ly9tYXhjZG4uYm9vdHN0cmFwY2RuLmNvbS9ib290c3RyYXAvMy4yLjAvY3NzL2Jvb3RzdHJhcC10aGVtZS5taW4uY3NzIi8+CiAgICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9Imh0dHBzOi8vbWF4Y2RuLmJvb3RzdHJhcGNkbi5jb20vZm9udC1hd2Vzb21lLzQuNi4zL2Nzcy9mb250LWF3ZXNvbWUubWluLmNzcyIvPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL2NkbmpzLmNsb3VkZmxhcmUuY29tL2FqYXgvbGlicy9MZWFmbGV0LmF3ZXNvbWUtbWFya2Vycy8yLjAuMi9sZWFmbGV0LmF3ZXNvbWUtbWFya2Vycy5jc3MiLz4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cHM6Ly9yYXdnaXQuY29tL3B5dGhvbi12aXN1YWxpemF0aW9uL2ZvbGl1bS9tYXN0ZXIvZm9saXVtL3RlbXBsYXRlcy9sZWFmbGV0LmF3ZXNvbWUucm90YXRlLmNzcyIvPgogICAgPHN0eWxlPmh0bWwsIGJvZHkge3dpZHRoOiAxMDAlO2hlaWdodDogMTAwJTttYXJnaW46IDA7cGFkZGluZzogMDt9PC9zdHlsZT4KICAgIDxzdHlsZT4jbWFwIHtwb3NpdGlvbjphYnNvbHV0ZTt0b3A6MDtib3R0b206MDtyaWdodDowO2xlZnQ6MDt9PC9zdHlsZT4KICAgIAogICAgICAgICAgICA8c3R5bGU+ICNtYXBfYmMzZmNhMmNlMjAxNGUxZWIwYjg2ZWNmYTUyYWRmY2UgewogICAgICAgICAgICAgICAgcG9zaXRpb24gOiByZWxhdGl2ZTsKICAgICAgICAgICAgICAgIHdpZHRoIDogMTAwLjAlOwogICAgICAgICAgICAgICAgaGVpZ2h0OiAxMDAuMCU7CiAgICAgICAgICAgICAgICBsZWZ0OiAwLjAlOwogICAgICAgICAgICAgICAgdG9wOiAwLjAlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICA8L3N0eWxlPgogICAgICAgIAo8L2hlYWQ+Cjxib2R5PiAgICAKICAgIAogICAgICAgICAgICA8ZGl2IGNsYXNzPSJmb2xpdW0tbWFwIiBpZD0ibWFwX2JjM2ZjYTJjZTIwMTRlMWViMGI4NmVjZmE1MmFkZmNlIiA+PC9kaXY+CiAgICAgICAgCjwvYm9keT4KPHNjcmlwdD4gICAgCiAgICAKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGJvdW5kcyA9IG51bGw7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgdmFyIG1hcF9iYzNmY2EyY2UyMDE0ZTFlYjBiODZlY2ZhNTJhZGZjZSA9IEwubWFwKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ21hcF9iYzNmY2EyY2UyMDE0ZTFlYjBiODZlY2ZhNTJhZGZjZScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7Y2VudGVyOiBbNDguODU2NjEwMSwyLjM1MTQ5OTJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgem9vbTogMTIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXhCb3VuZHM6IGJvdW5kcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxheWVyczogW10sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3b3JsZENvcHlKdW1wOiBmYWxzZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNyczogTC5DUlMuRVBTRzM4NTcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciB0aWxlX2xheWVyX2E2NDIxODhiMTg0MzRhMTk5MzBkMjQ1OTFlZjY0NTAyID0gTC50aWxlTGF5ZXIoCiAgICAgICAgICAgICAgICAnaHR0cHM6Ly97c30udGlsZS5vcGVuc3RyZWV0bWFwLm9yZy97en0ve3h9L3t5fS5wbmcnLAogICAgICAgICAgICAgICAgewogICJhdHRyaWJ1dGlvbiI6IG51bGwsCiAgImRldGVjdFJldGluYSI6IGZhbHNlLAogICJtYXhab29tIjogMTgsCiAgIm1pblpvb20iOiAxLAogICJub1dyYXAiOiBmYWxzZSwKICAic3ViZG9tYWlucyI6ICJhYmMiCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2JjM2ZjYTJjZTIwMTRlMWViMGI4NmVjZmE1MmFkZmNlKTsKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8yZWEyMTA0NWExMGQ0MmMzYmRjOWQzODc4ZmQzYmY4MSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQ4Ljg2MjU2MjcwMTgsMi4zMzY0NDMzNjIwNV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICIjODBmZmI0IiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzgwZmZiNCIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9iYzNmY2EyY2UyMDE0ZTFlYjBiODZlY2ZhNTJhZGZjZSk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF9iYjdhY2E5NTBiNDQ0YWVjODIxNjU0ZjM5YWVhNmQyNyA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF8zNTViOGZmMTU2NTE0YWZlYjVlMWY0Zjg0ZWViNDZmMyA9ICQoJzxkaXYgaWQ9Imh0bWxfMzU1YjhmZjE1NjUxNGFmZWI1ZTFmNGY4NGVlYjQ2ZjMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkxvdXZyZUNsdXN0ZXIzPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9iYjdhY2E5NTBiNDQ0YWVjODIxNjU0ZjM5YWVhNmQyNy5zZXRDb250ZW50KGh0bWxfMzU1YjhmZjE1NjUxNGFmZWI1ZTFmNGY4NGVlYjQ2ZjMpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfMmVhMjEwNDVhMTBkNDJjM2JkYzlkMzg3OGZkM2JmODEuYmluZFBvcHVwKHBvcHVwX2JiN2FjYTk1MGI0NDRhZWM4MjE2NTRmMzlhZWE2ZDI3KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzBmMTkyODg3OWI4ODQyZjA4NzMzMWM0NzJjYWI4MmNmID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDguODY4Mjc5MjIyNSwyLjM0MjgwMjU0Njg5XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogIiM4MDAwZmYiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjODAwMGZmIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2JjM2ZjYTJjZTIwMTRlMWViMGI4NmVjZmE1MmFkZmNlKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2Y1ZmEwMDZjMDdhYTQ5N2U4MDMzZmExMjY5NDFkZmFhID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzNiY2QyMzUwZjhhNjQzZjQ5NzM3ZGM2MjYwZGNjOTY5ID0gJCgnPGRpdiBpZD0iaHRtbF8zYmNkMjM1MGY4YTY0M2Y0OTczN2RjNjI2MGRjYzk2OSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+Qm91cnNlQ2x1c3RlcjE8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2Y1ZmEwMDZjMDdhYTQ5N2U4MDMzZmExMjY5NDFkZmFhLnNldENvbnRlbnQoaHRtbF8zYmNkMjM1MGY4YTY0M2Y0OTczN2RjNjI2MGRjYzk2OSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl8wZjE5Mjg4NzliODg0MmYwODczMzFjNDcyY2FiODJjZi5iaW5kUG9wdXAocG9wdXBfZjVmYTAwNmMwN2FhNDk3ZTgwMzNmYTEyNjk0MWRmYWEpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfZDJlNzk5N2JlMTg5NDdiMDg5ODA1OTZkYmFmNjY2MGUgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0OC44NjI4NzIzOCwyLjM2MDAwMDk4NTldLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiIzgwMDBmZiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiM4MDAwZmYiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfYmMzZmNhMmNlMjAxNGUxZWIwYjg2ZWNmYTUyYWRmY2UpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfMWU3YzczYzI5NDI0NGZiNzlmYmFkYjRiZmNiZjliMDQgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNjg0NjhkMGY4YTJlNDFhOWFiMDc1MjVjOGY4YzZlMmUgPSAkKCc8ZGl2IGlkPSJodG1sXzY4NDY4ZDBmOGEyZTQxYTlhYjA3NTI1YzhmOGM2ZTJlIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5UZW1wbGVDbHVzdGVyMTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMWU3YzczYzI5NDI0NGZiNzlmYmFkYjRiZmNiZjliMDQuc2V0Q29udGVudChodG1sXzY4NDY4ZDBmOGEyZTQxYTlhYjA3NTI1YzhmOGM2ZTJlKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyX2QyZTc5OTdiZTE4OTQ3YjA4OTgwNTk2ZGJhZjY2NjBlLmJpbmRQb3B1cChwb3B1cF8xZTdjNzNjMjk0MjQ0ZmI3OWZiYWRiNGJmY2JmOWIwNCk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl81ZmVmZGM1NTAxYTY0MzgxOWMxZGJlOGQ3ZjdkMTMyMCA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQ4Ljg1NDM0MTQyNjMsMi4zNTc2Mjk2MjAzMl0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICIjODAwMGZmIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9iYzNmY2EyY2UyMDE0ZTFlYjBiODZlY2ZhNTJhZGZjZSk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF8xZWU2MWIwZGM0NTQ0MWEwOTdjMDQ5MDdhY2U0YmRhMSA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF84MDU5ZTI0Y2UyMDE0OTczOGMxMDM1MDRhYTc0NGIyYyA9ICQoJzxkaXYgaWQ9Imh0bWxfODA1OWUyNGNlMjAxNDk3MzhjMTAzNTA0YWE3NDRiMmMiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkjDtHRlbC1kZS1WaWxsZUNsdXN0ZXIxPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8xZWU2MWIwZGM0NTQ0MWEwOTdjMDQ5MDdhY2U0YmRhMS5zZXRDb250ZW50KGh0bWxfODA1OWUyNGNlMjAxNDk3MzhjMTAzNTA0YWE3NDRiMmMpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfNWZlZmRjNTUwMWE2NDM4MTljMWRiZThkN2Y3ZDEzMjAuYmluZFBvcHVwKHBvcHVwXzFlZTYxYjBkYzQ1NDQxYTA5N2MwNDkwN2FjZTRiZGExKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzVlNDMxNWNiYTUyNDQwNTc5M2MwZWE4MmQ0NzIyYTIwID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDguODQ0NDQzMTUwNSwyLjM1MDcxNDYwOTU4XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogIiM4MGZmYjQiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjODBmZmI0IiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2JjM2ZjYTJjZTIwMTRlMWViMGI4NmVjZmE1MmFkZmNlKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2RmOTllYWY2MGMzZDQ2ZjM4ZTNmODBjODZiYmI5ZjQyID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzJiMmUyYTdlMjAyNDRiZWJhNDAzYzQwZjU2MGJmYTg4ID0gJCgnPGRpdiBpZD0iaHRtbF8yYjJlMmE3ZTIwMjQ0YmViYTQwM2M0MGY1NjBiZmE4OCIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+UGFudGjDqW9uQ2x1c3RlcjM8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2RmOTllYWY2MGMzZDQ2ZjM4ZTNmODBjODZiYmI5ZjQyLnNldENvbnRlbnQoaHRtbF8yYjJlMmE3ZTIwMjQ0YmViYTQwM2M0MGY1NjBiZmE4OCk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl81ZTQzMTVjYmE1MjQ0MDU3OTNjMGVhODJkNDcyMmEyMC5iaW5kUG9wdXAocG9wdXBfZGY5OWVhZjYwYzNkNDZmMzhlM2Y4MGM4NmJiYjlmNDIpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfYmEzZWY0NzNjZmFkNGUyNzljYTFkNWVhNTg5MDlkNTMgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0OC44NDkxMzAzNTg2LDIuMzMyODk3OTk5MDVdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiIzgwMDBmZiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiM4MDAwZmYiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfYmMzZmNhMmNlMjAxNGUxZWIwYjg2ZWNmYTUyYWRmY2UpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYzJmZjhmMzMzZjViNDFhODhmNmU3YWIzMjgxNzZjZmUgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfYjcyZWE3NDFmNDhmNDg0OTgwZjUyNGExZjNmNzZhODUgPSAkKCc8ZGl2IGlkPSJodG1sX2I3MmVhNzQxZjQ4ZjQ4NDk4MGY1MjRhMWYzZjc2YTg1IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5MdXhlbWJvdXJnQ2x1c3RlcjE8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2MyZmY4ZjMzM2Y1YjQxYTg4ZjZlN2FiMzI4MTc2Y2ZlLnNldENvbnRlbnQoaHRtbF9iNzJlYTc0MWY0OGY0ODQ5ODBmNTI0YTFmM2Y3NmE4NSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9iYTNlZjQ3M2NmYWQ0ZTI3OWNhMWQ1ZWE1ODkwOWQ1My5iaW5kUG9wdXAocG9wdXBfYzJmZjhmMzMzZjViNDFhODhmNmU3YWIzMjgxNzZjZmUpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNjVjM2NmMTE0YzdlNDM3YzhhOGJmNjk2NDYxYWE1YjkgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0OC44NTYxNzQ0Mjg4LDIuMzEyMTg3NjkxNDhdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiI2ZmYjM2MCIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiNmZmIzNjAiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfYmMzZmNhMmNlMjAxNGUxZWIwYjg2ZWNmYTUyYWRmY2UpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfOTc0MDU0ODI5OGRkNGNiNGE0N2EwMjg4OWRiMzk0YmMgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfOTUxZWE1NzZhN2E4NGI1ZmE0N2Y0OTdiMjE0M2Y1M2EgPSAkKCc8ZGl2IGlkPSJodG1sXzk1MWVhNTc2YTdhODRiNWZhNDdmNDk3YjIxNDNmNTNhIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5QYWxhaXMtQm91cmJvbkNsdXN0ZXI0PC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF85NzQwNTQ4Mjk4ZGQ0Y2I0YTQ3YTAyODg5ZGIzOTRiYy5zZXRDb250ZW50KGh0bWxfOTUxZWE1NzZhN2E4NGI1ZmE0N2Y0OTdiMjE0M2Y1M2EpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfNjVjM2NmMTE0YzdlNDM3YzhhOGJmNjk2NDYxYWE1YjkuYmluZFBvcHVwKHBvcHVwXzk3NDA1NDgyOThkZDRjYjRhNDdhMDI4ODlkYjM5NGJjKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2RhNzlmNGRjODE2YjQ3MTI5NGRiN2Y5NDA4OGZmNDVjID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDguODcyNzIwODM3NCwyLjMxMjU1NDAyMjRdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiIzgwMDBmZiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiM4MDAwZmYiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfYmMzZmNhMmNlMjAxNGUxZWIwYjg2ZWNmYTUyYWRmY2UpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfOTRkZDY1MDhiZmQ5NGQzY2E3YTE5MTIzM2ViZmE2MWEgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZjQ1MGE3ODI2NzdmNDRhY2EyYzJiY2M4ZjU0NzYyZTUgPSAkKCc8ZGl2IGlkPSJodG1sX2Y0NTBhNzgyNjc3ZjQ0YWNhMmMyYmNjOGY1NDc2MmU1IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5FbHlzw6llQ2x1c3RlcjE8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzk0ZGQ2NTA4YmZkOTRkM2NhN2ExOTEyMzNlYmZhNjFhLnNldENvbnRlbnQoaHRtbF9mNDUwYTc4MjY3N2Y0NGFjYTJjMmJjYzhmNTQ3NjJlNSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9kYTc5ZjRkYzgxNmI0NzEyOTRkYjdmOTQwODhmZjQ1Yy5iaW5kUG9wdXAocG9wdXBfOTRkZDY1MDhiZmQ5NGQzY2E3YTE5MTIzM2ViZmE2MWEpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfNTdhM2IzZmU2YjMzNGU5Y2FhMjZmMTE3YTk3YTg4MzkgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0OC44NzcxNjM1MTczLDIuMzM3NDU3NTQzNDhdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiIzgwMDBmZiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiM4MDAwZmYiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfYmMzZmNhMmNlMjAxNGUxZWIwYjg2ZWNmYTUyYWRmY2UpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYzk5NzAzMmI4N2JkNDMwM2FjYWFlNjQ2NTEwYjEyMTAgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNzQxNzQ0YWY5MTJkNDNmZmJkNTMxODYzZTZhMTE1YjMgPSAkKCc8ZGl2IGlkPSJodG1sXzc0MTc0NGFmOTEyZDQzZmZiZDUzMTg2M2U2YTExNWIzIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5PcMOpcmFDbHVzdGVyMTwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfYzk5NzAzMmI4N2JkNDMwM2FjYWFlNjQ2NTEwYjEyMTAuc2V0Q29udGVudChodG1sXzc0MTc0NGFmOTEyZDQzZmZiZDUzMTg2M2U2YTExNWIzKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzU3YTNiM2ZlNmIzMzRlOWNhYTI2ZjExN2E5N2E4ODM5LmJpbmRQb3B1cChwb3B1cF9jOTk3MDMyYjg3YmQ0MzAzYWNhYWU2NDY1MTBiMTIxMCk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8yODUxYmM2MWMxMjc0MTEyYWZlMWE1MzhhNTE4N2U2ZSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQ4Ljg3NjEzMDAzNjUsMi4zNjA3Mjg0ODc4NV0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICIjODAwMGZmIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9iYzNmY2EyY2UyMDE0ZTFlYjBiODZlY2ZhNTJhZGZjZSk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF8wMmY5Mjk3OWQxMWY0Mzk2OThjZTdmMDY4YjgzZTRmZiA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF9iMWM2ZDIwNmI5Mzg0YzBhOWQ2OTFkYWZlNzZmMWZkOSA9ICQoJzxkaXYgaWQ9Imh0bWxfYjFjNmQyMDZiOTM4NGMwYTlkNjkxZGFmZTc2ZjFmZDkiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPkVudHJlcMO0dENsdXN0ZXIxPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8wMmY5Mjk3OWQxMWY0Mzk2OThjZTdmMDY4YjgzZTRmZi5zZXRDb250ZW50KGh0bWxfYjFjNmQyMDZiOTM4NGMwYTlkNjkxZGFmZTc2ZjFmZDkpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfMjg1MWJjNjFjMTI3NDExMmFmZTFhNTM4YTUxODdlNmUuYmluZFBvcHVwKHBvcHVwXzAyZjkyOTc5ZDExZjQzOTY5OGNlN2YwNjhiODNlNGZmKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzRlNDExNDk3MTk3NDQ3N2M4ZTIzNTcyNWIyY2NkNzc0ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDguODU5MDU5MjIxMywyLjM4MDA1ODMwODJdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiIzgwMDBmZiIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiM4MDAwZmYiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfYmMzZmNhMmNlMjAxNGUxZWIwYjg2ZWNmYTUyYWRmY2UpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfZjFlNTE2ZWI0MTJhNDA0MDljMjYxNDY0Y2YxZGIzOWUgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfMGM0YzdkMzNkMGZmNDI5NGJlNTAwYzExYTYzZTc2MTYgPSAkKCc8ZGl2IGlkPSJodG1sXzBjNGM3ZDMzZDBmZjQyOTRiZTUwMGMxMWE2M2U3NjE2IiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Qb3BpbmNvdXJ0Q2x1c3RlcjE8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2YxZTUxNmViNDEyYTQwNDA5YzI2MTQ2NGNmMWRiMzllLnNldENvbnRlbnQoaHRtbF8wYzRjN2QzM2QwZmY0Mjk0YmU1MDBjMTFhNjNlNzYxNik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl80ZTQxMTQ5NzE5NzQ0NzdjOGUyMzU3MjViMmNjZDc3NC5iaW5kUG9wdXAocG9wdXBfZjFlNTE2ZWI0MTJhNDA0MDljMjYxNDY0Y2YxZGIzOWUpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfZDE2NDg3Yjk1ZTE4NGQ5ZWIwMjM3ZDRmMWNjODAwNWMgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0OC44MzQ5NzQzODE1LDIuNDIxMzI0OTAwNzhdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiIzgwZmZiNCIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiM4MGZmYjQiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfYmMzZmNhMmNlMjAxNGUxZWIwYjg2ZWNmYTUyYWRmY2UpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfNDA4NDBmMDk5ZmRkNDY4YWFmZjExNTQ0OGU3Y2Q5MjMgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfY2M2YmFhNjZhNzFjNDcwMTgxMDQzODAzZWE1M2E3Y2MgPSAkKCc8ZGl2IGlkPSJodG1sX2NjNmJhYTY2YTcxYzQ3MDE4MTA0MzgwM2VhNTNhN2NjIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5SZXVpbGx5Q2x1c3RlcjM8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwXzQwODQwZjA5OWZkZDQ2OGFhZmYxMTU0NDhlN2NkOTIzLnNldENvbnRlbnQoaHRtbF9jYzZiYWE2NmE3MWM0NzAxODEwNDM4MDNlYTUzYTdjYyk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9kMTY0ODdiOTVlMTg0ZDllYjAyMzdkNGYxY2M4MDA1Yy5iaW5kUG9wdXAocG9wdXBfNDA4NDBmMDk5ZmRkNDY4YWFmZjExNTQ0OGU3Y2Q5MjMpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfMTc3MGVjZmRmZjk2NGI4OTljZWM0NmUxZWZmZTlkMmMgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0OC44MjgzODgwMzE3LDIuMzYyMjcyNDQwNDJdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiIzgwZmZiNCIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiM4MGZmYjQiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfYmMzZmNhMmNlMjAxNGUxZWIwYjg2ZWNmYTUyYWRmY2UpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfYmIxMTBjOTExMGEzNDAxY2I1NDg4MzQ2MzRmZGFjNWEgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfZDIzMGI0M2I0MDc0NDI4NmIyNGUxY2VmNWFlOTU2ZWMgPSAkKCc8ZGl2IGlkPSJodG1sX2QyMzBiNDNiNDA3NDQyODZiMjRlMWNlZjVhZTk1NmVjIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Hb2JlbGluc0NsdXN0ZXIzPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF9iYjExMGM5MTEwYTM0MDFjYjU0ODgzNDYzNGZkYWM1YS5zZXRDb250ZW50KGh0bWxfZDIzMGI0M2I0MDc0NDI4NmIyNGUxY2VmNWFlOTU2ZWMpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfMTc3MGVjZmRmZjk2NGI4OTljZWM0NmUxZWZmZTlkMmMuYmluZFBvcHVwKHBvcHVwX2JiMTEwYzkxMTBhMzQwMWNiNTQ4ODM0NjM0ZmRhYzVhKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzM1MTEwYjc3YzhiMTRlZmY4YWNjOGFhNzdkZTFkODBlID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDguODI5MjQ0NTAwNSwyLjMyNjU0MjA0NDJdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiIzgwZmZiNCIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiM4MGZmYjQiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfYmMzZmNhMmNlMjAxNGUxZWIwYjg2ZWNmYTUyYWRmY2UpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfMmM4YjQzZTE4Y2Q1NDY2ZDhiNzdiZGZiOGVkMDQwMTEgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNDM1NDUyNGJlZDM4NGRjNmEwMzI3ZTYzYTA3YWIzYWMgPSAkKCc8ZGl2IGlkPSJodG1sXzQzNTQ1MjRiZWQzODRkYzZhMDMyN2U2M2EwN2FiM2FjIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5PYnNlcnZhdG9pcmVDbHVzdGVyMzwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfMmM4YjQzZTE4Y2Q1NDY2ZDhiNzdiZGZiOGVkMDQwMTEuc2V0Q29udGVudChodG1sXzQzNTQ1MjRiZWQzODRkYzZhMDMyN2U2M2EwN2FiM2FjKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzM1MTEwYjc3YzhiMTRlZmY4YWNjOGFhNzdkZTFkODBlLmJpbmRQb3B1cChwb3B1cF8yYzhiNDNlMThjZDU0NjZkOGI3N2JkZmI4ZWQwNDAxMSk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8yNDczYjJmZjNhNzY0YmU3OGY4NzNhYzk4YjE0NjI3MyA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQ4Ljg0MDA4NTM3NTksMi4yOTI4MjU4MjI0Ml0sCiAgICAgICAgICAgICAgICB7CiAgImJ1YmJsaW5nTW91c2VFdmVudHMiOiB0cnVlLAogICJjb2xvciI6ICIjODAwMGZmIiwKICAiZGFzaEFycmF5IjogbnVsbCwKICAiZGFzaE9mZnNldCI6IG51bGwsCiAgImZpbGwiOiB0cnVlLAogICJmaWxsQ29sb3IiOiAiIzgwMDBmZiIsCiAgImZpbGxPcGFjaXR5IjogMC43LAogICJmaWxsUnVsZSI6ICJldmVub2RkIiwKICAibGluZUNhcCI6ICJyb3VuZCIsCiAgImxpbmVKb2luIjogInJvdW5kIiwKICAib3BhY2l0eSI6IDEuMCwKICAicmFkaXVzIjogNSwKICAic3Ryb2tlIjogdHJ1ZSwKICAid2VpZ2h0IjogMwp9CiAgICAgICAgICAgICAgICApLmFkZFRvKG1hcF9iYzNmY2EyY2UyMDE0ZTFlYjBiODZlY2ZhNTJhZGZjZSk7CiAgICAgICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBwb3B1cF80Nzk3OWQ4OTRlYTM0NWYxODhkMzQ1MDhjODA5NThiMyA9IEwucG9wdXAoe21heFdpZHRoOiAnMzAwJ30pOwoKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB2YXIgaHRtbF81YWRmODlhMDNiMDM0ZTI5OTQ0YTU2OTA4MThiNzM5YiA9ICQoJzxkaXYgaWQ9Imh0bWxfNWFkZjg5YTAzYjAzNGUyOTk0NGE1NjkwODE4YjczOWIiIHN0eWxlPSJ3aWR0aDogMTAwLjAlOyBoZWlnaHQ6IDEwMC4wJTsiPlZhdWdpcmFyZENsdXN0ZXIxPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF80Nzk3OWQ4OTRlYTM0NWYxODhkMzQ1MDhjODA5NThiMy5zZXRDb250ZW50KGh0bWxfNWFkZjg5YTAzYjAzNGUyOTk0NGE1NjkwODE4YjczOWIpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfMjQ3M2IyZmYzYTc2NGJlNzhmODczYWM5OGIxNDYyNzMuYmluZFBvcHVwKHBvcHVwXzQ3OTc5ZDg5NGVhMzQ1ZjE4OGQzNDUwOGM4MDk1OGIzKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzdmNmQ1NzIzZWVkNTRhMDE5MzljZTRiYTQ5YmNkZmY4ID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDguODYwMzkyMTA1NCwyLjI2MTk3MDc4ODM2XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogIiMwMGI1ZWIiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjMDBiNWViIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2JjM2ZjYTJjZTIwMTRlMWViMGI4NmVjZmE1MmFkZmNlKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzhjMjU5ODUxZjhkOTQ3NGQ4MjU3YTEyZTkxYTU0ZjUwID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sX2I4ZWJkNDJkZjNmNTRlYjY4ZDc2NzE4NTI5YTJhODdiID0gJCgnPGRpdiBpZD0iaHRtbF9iOGViZDQyZGYzZjU0ZWI2OGQ3NjcxODUyOWEyYTg3YiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+UGFzc3lDbHVzdGVyMjwvZGl2PicpWzBdOwogICAgICAgICAgICAgICAgcG9wdXBfOGMyNTk4NTFmOGQ5NDc0ZDgyNTdhMTJlOTFhNTRmNTAuc2V0Q29udGVudChodG1sX2I4ZWJkNDJkZjNmNTRlYjY4ZDc2NzE4NTI5YTJhODdiKTsKICAgICAgICAgICAgCgogICAgICAgICAgICBjaXJjbGVfbWFya2VyXzdmNmQ1NzIzZWVkNTRhMDE5MzljZTRiYTQ5YmNkZmY4LmJpbmRQb3B1cChwb3B1cF84YzI1OTg1MWY4ZDk0NzRkODI1N2ExMmU5MWE1NGY1MCk7CgogICAgICAgICAgICAKICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgY2lyY2xlX21hcmtlcl8zYjBmZmQyNzVlNmM0OGU5OGNkYjc4MjQzZDUyZDcyOSA9IEwuY2lyY2xlTWFya2VyKAogICAgICAgICAgICAgICAgWzQ4Ljg4NzMyNjUyMiwyLjMwNjc3Njk5MDU3XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogIiM4MDAwZmYiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjODAwMGZmIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2JjM2ZjYTJjZTIwMTRlMWViMGI4NmVjZmE1MmFkZmNlKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwXzczZmEyYWQyZmFkOTRlNTY4MzRkZjdiNmQ3MmFmYTMxID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzhjZjA3ZmExYTgwZjQzOGI4MDc2NGM4NDI2MmVjZTA5ID0gJCgnPGRpdiBpZD0iaHRtbF84Y2YwN2ZhMWE4MGY0MzhiODA3NjRjODQyNjJlY2UwOSIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+QmF0aWdub2xsZXMtTW9uY2VhdUNsdXN0ZXIxPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF83M2ZhMmFkMmZhZDk0ZTU2ODM0ZGY3YjZkNzJhZmEzMS5zZXRDb250ZW50KGh0bWxfOGNmMDdmYTFhODBmNDM4YjgwNzY0Yzg0MjYyZWNlMDkpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfM2IwZmZkMjc1ZTZjNDhlOThjZGI3ODI0M2Q1MmQ3MjkuYmluZFBvcHVwKHBvcHVwXzczZmEyYWQyZmFkOTRlNTY4MzRkZjdiNmQ3MmFmYTMxKTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyXzBiYTM4Mzg0NjA2ODQ1ODE5YzQ5ZTgwY2MxZjdiMzUzID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDguODkyNTY5MjY4LDIuMzQ4MTYwNTE5NTZdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiI2ZmMDAwMCIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiNmZjAwMDAiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfYmMzZmNhMmNlMjAxNGUxZWIwYjg2ZWNmYTUyYWRmY2UpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfMTJhZDAyNjA3ZTk0NGEwMDgzMjllM2M5MWFhOGM5OTggPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfNDhkMDhjMWZkYjRkNGNmZWFlN2RiNzgzMDBmNTdkNGEgPSAkKCc8ZGl2IGlkPSJodG1sXzQ4ZDA4YzFmZGI0ZDRjZmVhZTdkYjc4MzAwZjU3ZDRhIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5CdXR0ZXMtTW9udG1hcnRyZUNsdXN0ZXIwPC9kaXY+JylbMF07CiAgICAgICAgICAgICAgICBwb3B1cF8xMmFkMDI2MDdlOTQ0YTAwODMyOWUzYzkxYWE4Yzk5OC5zZXRDb250ZW50KGh0bWxfNDhkMDhjMWZkYjRkNGNmZWFlN2RiNzgzMDBmNTdkNGEpOwogICAgICAgICAgICAKCiAgICAgICAgICAgIGNpcmNsZV9tYXJrZXJfMGJhMzgzODQ2MDY4NDU4MTljNDllODBjYzFmN2IzNTMuYmluZFBvcHVwKHBvcHVwXzEyYWQwMjYwN2U5NDRhMDA4MzI5ZTNjOTFhYThjOTk4KTsKCiAgICAgICAgICAgIAogICAgICAgIAogICAgCiAgICAgICAgICAgIHZhciBjaXJjbGVfbWFya2VyX2UzMGI3NDk2YzExZDRkNmQ5ODczMGE1OWVjYTVlNjJjID0gTC5jaXJjbGVNYXJrZXIoCiAgICAgICAgICAgICAgICBbNDguODg3MDc1OTk2NiwyLjM4NDgyMDk2MDE1XSwKICAgICAgICAgICAgICAgIHsKICAiYnViYmxpbmdNb3VzZUV2ZW50cyI6IHRydWUsCiAgImNvbG9yIjogIiM4MDAwZmYiLAogICJkYXNoQXJyYXkiOiBudWxsLAogICJkYXNoT2Zmc2V0IjogbnVsbCwKICAiZmlsbCI6IHRydWUsCiAgImZpbGxDb2xvciI6ICIjODAwMGZmIiwKICAiZmlsbE9wYWNpdHkiOiAwLjcsCiAgImZpbGxSdWxlIjogImV2ZW5vZGQiLAogICJsaW5lQ2FwIjogInJvdW5kIiwKICAibGluZUpvaW4iOiAicm91bmQiLAogICJvcGFjaXR5IjogMS4wLAogICJyYWRpdXMiOiA1LAogICJzdHJva2UiOiB0cnVlLAogICJ3ZWlnaHQiOiAzCn0KICAgICAgICAgICAgICAgICkuYWRkVG8obWFwX2JjM2ZjYTJjZTIwMTRlMWViMGI4NmVjZmE1MmFkZmNlKTsKICAgICAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIHBvcHVwX2E1YzNlYTk1ODI2MjQzOGQ4MjliZmVlNTgyYzgyNzFjID0gTC5wb3B1cCh7bWF4V2lkdGg6ICczMDAnfSk7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIHZhciBodG1sXzAzOTRiNDgyYTUyMTQwYTM4ZGM5YWM4NWNkNzAzOTVmID0gJCgnPGRpdiBpZD0iaHRtbF8wMzk0YjQ4MmE1MjE0MGEzOGRjOWFjODVjZDcwMzk1ZiIgc3R5bGU9IndpZHRoOiAxMDAuMCU7IGhlaWdodDogMTAwLjAlOyI+QnV0dGVzLUNoYXVtb250Q2x1c3RlcjE8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2E1YzNlYTk1ODI2MjQzOGQ4MjliZmVlNTgyYzgyNzFjLnNldENvbnRlbnQoaHRtbF8wMzk0YjQ4MmE1MjE0MGEzOGRjOWFjODVjZDcwMzk1Zik7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9lMzBiNzQ5NmMxMWQ0ZDZkOTg3MzBhNTllY2E1ZTYyYy5iaW5kUG9wdXAocG9wdXBfYTVjM2VhOTU4MjYyNDM4ZDgyOWJmZWU1ODJjODI3MWMpOwoKICAgICAgICAgICAgCiAgICAgICAgCiAgICAKICAgICAgICAgICAgdmFyIGNpcmNsZV9tYXJrZXJfY2ViNzZkZGY0MjQ4NGQzZWFhZjY3ZDRiYzZmOTEzZDIgPSBMLmNpcmNsZU1hcmtlcigKICAgICAgICAgICAgICAgIFs0OC44NjM0NjA1Nzg5LDIuNDAxMTg4MTI5MjhdLAogICAgICAgICAgICAgICAgewogICJidWJibGluZ01vdXNlRXZlbnRzIjogdHJ1ZSwKICAiY29sb3IiOiAiIzgwZmZiNCIsCiAgImRhc2hBcnJheSI6IG51bGwsCiAgImRhc2hPZmZzZXQiOiBudWxsLAogICJmaWxsIjogdHJ1ZSwKICAiZmlsbENvbG9yIjogIiM4MGZmYjQiLAogICJmaWxsT3BhY2l0eSI6IDAuNywKICAiZmlsbFJ1bGUiOiAiZXZlbm9kZCIsCiAgImxpbmVDYXAiOiAicm91bmQiLAogICJsaW5lSm9pbiI6ICJyb3VuZCIsCiAgIm9wYWNpdHkiOiAxLjAsCiAgInJhZGl1cyI6IDUsCiAgInN0cm9rZSI6IHRydWUsCiAgIndlaWdodCI6IDMKfQogICAgICAgICAgICAgICAgKS5hZGRUbyhtYXBfYmMzZmNhMmNlMjAxNGUxZWIwYjg2ZWNmYTUyYWRmY2UpOwogICAgICAgICAgICAKICAgIAogICAgICAgICAgICB2YXIgcG9wdXBfZGM2MDIyMTU0ZTFkNGI1MDkxZjM3ODU3NmIwMDZkODIgPSBMLnBvcHVwKHttYXhXaWR0aDogJzMwMCd9KTsKCiAgICAgICAgICAgIAogICAgICAgICAgICAgICAgdmFyIGh0bWxfODJlYjE1MGI2OWZkNGJlN2JiNmE0MDRkZTk3MzMzZTEgPSAkKCc8ZGl2IGlkPSJodG1sXzgyZWIxNTBiNjlmZDRiZTdiYjZhNDA0ZGU5NzMzM2UxIiBzdHlsZT0id2lkdGg6IDEwMC4wJTsgaGVpZ2h0OiAxMDAuMCU7Ij5Nw6luaWxtb250YW50Q2x1c3RlcjM8L2Rpdj4nKVswXTsKICAgICAgICAgICAgICAgIHBvcHVwX2RjNjAyMjE1NGUxZDRiNTA5MWYzNzg1NzZiMDA2ZDgyLnNldENvbnRlbnQoaHRtbF84MmViMTUwYjY5ZmQ0YmU3YmI2YTQwNGRlOTczMzNlMSk7CiAgICAgICAgICAgIAoKICAgICAgICAgICAgY2lyY2xlX21hcmtlcl9jZWI3NmRkZjQyNDg0ZDNlYWFmNjdkNGJjNmY5MTNkMi5iaW5kUG9wdXAocG9wdXBfZGM2MDIyMTU0ZTFkNGI1MDkxZjM3ODU3NmIwMDZkODIpOwoKICAgICAgICAgICAgCiAgICAgICAgCjwvc2NyaXB0Pg==\" style=\"position:absolute;width:100%;height:100%;left:0;top:0;border:none !important;\" allowfullscreen webkitallowfullscreen mozallowfullscreen></iframe></div></div>"
],
"text/plain": [
"<folium.folium.Map at 0x7f750f66b6d8>"
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"map_clusters = folium.Map(location=[latitude_par, longitude_par], zoom_start=12)\n",
"# set color scheme for the clusters\n",
"x = np.arange(kclusters)\n",
"ys = [i+x+(i*x)**2 for i in range(kclusters)]\n",
"colors_array = cm.rainbow(np.linspace(0, 1, len(ys)))\n",
"rainbow = [colors.rgb2hex(i) for i in colors_array]\n",
"# add markers to the map\n",
"markers_colors = []\n",
"for lat, lon, poi, cluster in zip(paris_merged[\"Latitude\"], paris_merged[\"Longitude\"], paris_merged[\"Neighborhood\"], paris_merged[\"Cluster Labels\"]):\n",
" label = folium.Popup(str(poi) + \"Cluster\" + str(cluster), parse_html=True)\n",
" folium.CircleMarker(\n",
" [lat, lon],\n",
" radius = 5,\n",
" popup = label,\n",
" color = rainbow[cluster-1],\n",
" fill = True,\n",
" fill_color = rainbow[cluster-1],\n",
" fill_opacity = 0.7).add_to(map_clusters) \n",
"map_clusters"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Cluster 1: Red"
]
},
{
"cell_type": "code",
"execution_count": 21,
"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>1st Most Common Venue</th>\n",
" <th>2nd Most Common Venue</th>\n",
" <th>3rd Most Common Venue</th>\n",
" <th>4th Most Common Venue</th>\n",
" <th>5th Most Common Venue</th>\n",
" <th>6th Most Common Venue</th>\n",
" <th>7th Most Common Venue</th>\n",
" <th>8th Most Common Venue</th>\n",
" <th>9th Most Common Venue</th>\n",
" <th>10th Most Common Venue</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>17</th>\n",
" <td>Buttes-Montmartre</td>\n",
" <td>French Restaurant</td>\n",
" <td>Bar</td>\n",
" <td>Pizza Place</td>\n",
" <td>Bistro</td>\n",
" <td>Italian Restaurant</td>\n",
" <td>Coffee Shop</td>\n",
" <td>Café</td>\n",
" <td>Art Gallery</td>\n",
" <td>Middle Eastern Restaurant</td>\n",
" <td>Convenience Store</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Neighborhood 1st Most Common Venue 2nd Most Common Venue \\\n",
"17 Buttes-Montmartre French Restaurant Bar \n",
"\n",
" 3rd Most Common Venue 4th Most Common Venue 5th Most Common Venue \\\n",
"17 Pizza Place Bistro Italian Restaurant \n",
"\n",
" 6th Most Common Venue 7th Most Common Venue 8th Most Common Venue \\\n",
"17 Coffee Shop Café Art Gallery \n",
"\n",
" 9th Most Common Venue 10th Most Common Venue \n",
"17 Middle Eastern Restaurant Convenience Store "
]
},
"execution_count": 21,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"paris_merged.loc[paris_merged[\"Cluster Labels\"] == 0, paris_merged.columns[[1] + list(range(5, paris_merged.shape[1]))]]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Most common venues in Cluster 1 are restauration services consisting of restaurants, Bars and Café shops. This represents 80% of the venues. \n",
"Opportunities exists here for the establishment of other businesses like Hotels, banks, book stores, education services, Insurance, Shopping Centers, etc."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Cluster 2: Purple"
]
},
{
"cell_type": "code",
"execution_count": 23,
"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>1st Most Common Venue</th>\n",
" <th>2nd Most Common Venue</th>\n",
" <th>3rd Most Common Venue</th>\n",
" <th>4th Most Common Venue</th>\n",
" <th>5th Most Common Venue</th>\n",
" <th>6th Most Common Venue</th>\n",
" <th>7th Most Common Venue</th>\n",
" <th>8th Most Common Venue</th>\n",
" <th>9th Most Common Venue</th>\n",
" <th>10th Most Common Venue</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>Bourse</td>\n",
" <td>French Restaurant</td>\n",
" <td>Bistro</td>\n",
" <td>Wine Bar</td>\n",
" <td>Cocktail Bar</td>\n",
" <td>Italian Restaurant</td>\n",
" <td>Boutique</td>\n",
" <td>Japanese Restaurant</td>\n",
" <td>Bakery</td>\n",
" <td>Creperie</td>\n",
" <td>Hotel</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>Temple</td>\n",
" <td>French Restaurant</td>\n",
" <td>Art Gallery</td>\n",
" <td>Coffee Shop</td>\n",
" <td>Gourmet Shop</td>\n",
" <td>Wine Bar</td>\n",
" <td>Italian Restaurant</td>\n",
" <td>Chinese Restaurant</td>\n",
" <td>Moroccan Restaurant</td>\n",
" <td>Sandwich Place</td>\n",
" <td>Cocktail Bar</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>Hôtel-de-Ville</td>\n",
" <td>French Restaurant</td>\n",
" <td>Ice Cream Shop</td>\n",
" <td>Plaza</td>\n",
" <td>Wine Bar</td>\n",
" <td>Tapas Restaurant</td>\n",
" <td>Pastry Shop</td>\n",
" <td>Bakery</td>\n",
" <td>Cocktail Bar</td>\n",
" <td>Clothing Store</td>\n",
" <td>Gastropub</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>Luxembourg</td>\n",
" <td>French Restaurant</td>\n",
" <td>Hotel</td>\n",
" <td>Italian Restaurant</td>\n",
" <td>Wine Bar</td>\n",
" <td>Chocolate Shop</td>\n",
" <td>Bistro</td>\n",
" <td>Seafood Restaurant</td>\n",
" <td>Tea Room</td>\n",
" <td>Plaza</td>\n",
" <td>Pastry Shop</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7</th>\n",
" <td>Elysée</td>\n",
" <td>French Restaurant</td>\n",
" <td>Hotel</td>\n",
" <td>Art Gallery</td>\n",
" <td>Italian Restaurant</td>\n",
" <td>Bakery</td>\n",
" <td>Theater</td>\n",
" <td>Clothing Store</td>\n",
" <td>Japanese Restaurant</td>\n",
" <td>Thai Restaurant</td>\n",
" <td>Boutique</td>\n",
" </tr>\n",
" <tr>\n",
" <th>8</th>\n",
" <td>Opéra</td>\n",
" <td>French Restaurant</td>\n",
" <td>Hotel</td>\n",
" <td>Cocktail Bar</td>\n",
" <td>Italian Restaurant</td>\n",
" <td>Bistro</td>\n",
" <td>Bar</td>\n",
" <td>Bakery</td>\n",
" <td>Wine Bar</td>\n",
" <td>Lounge</td>\n",
" <td>Pizza Place</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9</th>\n",
" <td>Entrepôt</td>\n",
" <td>French Restaurant</td>\n",
" <td>Coffee Shop</td>\n",
" <td>Bistro</td>\n",
" <td>Pizza Place</td>\n",
" <td>Japanese Restaurant</td>\n",
" <td>Italian Restaurant</td>\n",
" <td>Bakery</td>\n",
" <td>Breakfast Spot</td>\n",
" <td>Indian Restaurant</td>\n",
" <td>Cocktail Bar</td>\n",
" </tr>\n",
" <tr>\n",
" <th>10</th>\n",
" <td>Popincourt</td>\n",
" <td>Bar</td>\n",
" <td>French Restaurant</td>\n",
" <td>Cocktail Bar</td>\n",
" <td>Bistro</td>\n",
" <td>Pizza Place</td>\n",
" <td>Italian Restaurant</td>\n",
" <td>Restaurant</td>\n",
" <td>Vegetarian / Vegan Restaurant</td>\n",
" <td>Beer Bar</td>\n",
" <td>Wine Bar</td>\n",
" </tr>\n",
" <tr>\n",
" <th>14</th>\n",
" <td>Vaugirard</td>\n",
" <td>French Restaurant</td>\n",
" <td>Hotel</td>\n",
" <td>Italian Restaurant</td>\n",
" <td>Coffee Shop</td>\n",
" <td>Bistro</td>\n",
" <td>Persian Restaurant</td>\n",
" <td>Lebanese Restaurant</td>\n",
" <td>Park</td>\n",
" <td>Restaurant</td>\n",
" <td>Japanese Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>16</th>\n",
" <td>Batignolles-Monceau</td>\n",
" <td>French Restaurant</td>\n",
" <td>Italian Restaurant</td>\n",
" <td>Hotel</td>\n",
" <td>Japanese Restaurant</td>\n",
" <td>Bakery</td>\n",
" <td>Restaurant</td>\n",
" <td>Café</td>\n",
" <td>Bistro</td>\n",
" <td>Plaza</td>\n",
" <td>Bar</td>\n",
" </tr>\n",
" <tr>\n",
" <th>18</th>\n",
" <td>Buttes-Chaumont</td>\n",
" <td>Bar</td>\n",
" <td>French Restaurant</td>\n",
" <td>Pizza Place</td>\n",
" <td>Hotel</td>\n",
" <td>Supermarket</td>\n",
" <td>Smoke Shop</td>\n",
" <td>Café</td>\n",
" <td>Bistro</td>\n",
" <td>Restaurant</td>\n",
" <td>Seafood Restaurant</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Neighborhood 1st Most Common Venue 2nd Most Common Venue \\\n",
"1 Bourse French Restaurant Bistro \n",
"2 Temple French Restaurant Art Gallery \n",
"3 Hôtel-de-Ville French Restaurant Ice Cream Shop \n",
"5 Luxembourg French Restaurant Hotel \n",
"7 Elysée French Restaurant Hotel \n",
"8 Opéra French Restaurant Hotel \n",
"9 Entrepôt French Restaurant Coffee Shop \n",
"10 Popincourt Bar French Restaurant \n",
"14 Vaugirard French Restaurant Hotel \n",
"16 Batignolles-Monceau French Restaurant Italian Restaurant \n",
"18 Buttes-Chaumont Bar French Restaurant \n",
"\n",
" 3rd Most Common Venue 4th Most Common Venue 5th Most Common Venue \\\n",
"1 Wine Bar Cocktail Bar Italian Restaurant \n",
"2 Coffee Shop Gourmet Shop Wine Bar \n",
"3 Plaza Wine Bar Tapas Restaurant \n",
"5 Italian Restaurant Wine Bar Chocolate Shop \n",
"7 Art Gallery Italian Restaurant Bakery \n",
"8 Cocktail Bar Italian Restaurant Bistro \n",
"9 Bistro Pizza Place Japanese Restaurant \n",
"10 Cocktail Bar Bistro Pizza Place \n",
"14 Italian Restaurant Coffee Shop Bistro \n",
"16 Hotel Japanese Restaurant Bakery \n",
"18 Pizza Place Hotel Supermarket \n",
"\n",
" 6th Most Common Venue 7th Most Common Venue 8th Most Common Venue \\\n",
"1 Boutique Japanese Restaurant Bakery \n",
"2 Italian Restaurant Chinese Restaurant Moroccan Restaurant \n",
"3 Pastry Shop Bakery Cocktail Bar \n",
"5 Bistro Seafood Restaurant Tea Room \n",
"7 Theater Clothing Store Japanese Restaurant \n",
"8 Bar Bakery Wine Bar \n",
"9 Italian Restaurant Bakery Breakfast Spot \n",
"10 Italian Restaurant Restaurant Vegetarian / Vegan Restaurant \n",
"14 Persian Restaurant Lebanese Restaurant Park \n",
"16 Restaurant Café Bistro \n",
"18 Smoke Shop Café Bistro \n",
"\n",
" 9th Most Common Venue 10th Most Common Venue \n",
"1 Creperie Hotel \n",
"2 Sandwich Place Cocktail Bar \n",
"3 Clothing Store Gastropub \n",
"5 Plaza Pastry Shop \n",
"7 Thai Restaurant Boutique \n",
"8 Lounge Pizza Place \n",
"9 Indian Restaurant Cocktail Bar \n",
"10 Beer Bar Wine Bar \n",
"14 Restaurant Japanese Restaurant \n",
"16 Plaza Bar \n",
"18 Restaurant Seafood Restaurant "
]
},
"execution_count": 23,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"paris_merged.loc[paris_merged[\"Cluster Labels\"] == 1, paris_merged.columns[[1] + list(range(5, paris_merged.shape[1]))]]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Cluster 2 has eleven neighbourhood consisting of mainly restauration services and hotels. This could also be a great location for the establishment of shpping centers, bakery and a banks"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Cluster 3: Blue "
]
},
{
"cell_type": "code",
"execution_count": 24,
"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>1st Most Common Venue</th>\n",
" <th>2nd Most Common Venue</th>\n",
" <th>3rd Most Common Venue</th>\n",
" <th>4th Most Common Venue</th>\n",
" <th>5th Most Common Venue</th>\n",
" <th>6th Most Common Venue</th>\n",
" <th>7th Most Common Venue</th>\n",
" <th>8th Most Common Venue</th>\n",
" <th>9th Most Common Venue</th>\n",
" <th>10th Most Common Venue</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>15</th>\n",
" <td>Passy</td>\n",
" <td>Plaza</td>\n",
" <td>Lake</td>\n",
" <td>Pool</td>\n",
" <td>French Restaurant</td>\n",
" <td>Garden</td>\n",
" <td>Diner</td>\n",
" <td>Skate Park</td>\n",
" <td>Bus Station</td>\n",
" <td>Bus Stop</td>\n",
" <td>Cafeteria</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Neighborhood 1st Most Common Venue 2nd Most Common Venue \\\n",
"15 Passy Plaza Lake \n",
"\n",
" 3rd Most Common Venue 4th Most Common Venue 5th Most Common Venue \\\n",
"15 Pool French Restaurant Garden \n",
"\n",
" 6th Most Common Venue 7th Most Common Venue 8th Most Common Venue \\\n",
"15 Diner Skate Park Bus Station \n",
"\n",
" 9th Most Common Venue 10th Most Common Venue \n",
"15 Bus Stop Cafeteria "
]
},
"execution_count": 24,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"paris_merged.loc[paris_merged[\"Cluster Labels\"] == 2, paris_merged.columns[[1] + list(range(5, paris_merged.shape[1]))]]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Cluster 3 also has one neighbourhood consisting of mainly restauration services and touristic sites. Business like banks or payment counters and hotels could also be established here"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Cluster 4: Green"
]
},
{
"cell_type": "code",
"execution_count": 25,
"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>1st Most Common Venue</th>\n",
" <th>2nd Most Common Venue</th>\n",
" <th>3rd Most Common Venue</th>\n",
" <th>4th Most Common Venue</th>\n",
" <th>5th Most Common Venue</th>\n",
" <th>6th Most Common Venue</th>\n",
" <th>7th Most Common Venue</th>\n",
" <th>8th Most Common Venue</th>\n",
" <th>9th Most Common Venue</th>\n",
" <th>10th Most Common Venue</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>Louvre</td>\n",
" <td>French Restaurant</td>\n",
" <td>Plaza</td>\n",
" <td>Hotel</td>\n",
" <td>Café</td>\n",
" <td>Japanese Restaurant</td>\n",
" <td>Exhibit</td>\n",
" <td>Historic Site</td>\n",
" <td>Udon Restaurant</td>\n",
" <td>Art Museum</td>\n",
" <td>Cosmetics Shop</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>Panthéon</td>\n",
" <td>French Restaurant</td>\n",
" <td>Bar</td>\n",
" <td>Wine Bar</td>\n",
" <td>Café</td>\n",
" <td>Hotel</td>\n",
" <td>Bakery</td>\n",
" <td>Plaza</td>\n",
" <td>Coffee Shop</td>\n",
" <td>Greek Restaurant</td>\n",
" <td>Museum</td>\n",
" </tr>\n",
" <tr>\n",
" <th>11</th>\n",
" <td>Reuilly</td>\n",
" <td>Lake</td>\n",
" <td>Zoo</td>\n",
" <td>Diner</td>\n",
" <td>Bus Stop</td>\n",
" <td>Exhibit</td>\n",
" <td>French Restaurant</td>\n",
" <td>Monument / Landmark</td>\n",
" <td>Japanese Restaurant</td>\n",
" <td>Hot Dog Joint</td>\n",
" <td>Fast Food Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>12</th>\n",
" <td>Gobelins</td>\n",
" <td>Vietnamese Restaurant</td>\n",
" <td>Thai Restaurant</td>\n",
" <td>Asian Restaurant</td>\n",
" <td>French Restaurant</td>\n",
" <td>Chinese Restaurant</td>\n",
" <td>Bakery</td>\n",
" <td>Hotel</td>\n",
" <td>Cantonese Restaurant</td>\n",
" <td>Japanese Restaurant</td>\n",
" <td>Cambodian Restaurant</td>\n",
" </tr>\n",
" <tr>\n",
" <th>13</th>\n",
" <td>Observatoire</td>\n",
" <td>French Restaurant</td>\n",
" <td>Hotel</td>\n",
" <td>Italian Restaurant</td>\n",
" <td>Bistro</td>\n",
" <td>Café</td>\n",
" <td>Bar</td>\n",
" <td>Vietnamese Restaurant</td>\n",
" <td>Plaza</td>\n",
" <td>Bakery</td>\n",
" <td>Pizza Place</td>\n",
" </tr>\n",
" <tr>\n",
" <th>19</th>\n",
" <td>Ménilmontant</td>\n",
" <td>French Restaurant</td>\n",
" <td>Bar</td>\n",
" <td>Bakery</td>\n",
" <td>Plaza</td>\n",
" <td>Bistro</td>\n",
" <td>Italian Restaurant</td>\n",
" <td>Café</td>\n",
" <td>Park</td>\n",
" <td>Bookstore</td>\n",
" <td>Supermarket</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Neighborhood 1st Most Common Venue 2nd Most Common Venue \\\n",
"0 Louvre French Restaurant Plaza \n",
"4 Panthéon French Restaurant Bar \n",
"11 Reuilly Lake Zoo \n",
"12 Gobelins Vietnamese Restaurant Thai Restaurant \n",
"13 Observatoire French Restaurant Hotel \n",
"19 Ménilmontant French Restaurant Bar \n",
"\n",
" 3rd Most Common Venue 4th Most Common Venue 5th Most Common Venue \\\n",
"0 Hotel Café Japanese Restaurant \n",
"4 Wine Bar Café Hotel \n",
"11 Diner Bus Stop Exhibit \n",
"12 Asian Restaurant French Restaurant Chinese Restaurant \n",
"13 Italian Restaurant Bistro Café \n",
"19 Bakery Plaza Bistro \n",
"\n",
" 6th Most Common Venue 7th Most Common Venue 8th Most Common Venue \\\n",
"0 Exhibit Historic Site Udon Restaurant \n",
"4 Bakery Plaza Coffee Shop \n",
"11 French Restaurant Monument / Landmark Japanese Restaurant \n",
"12 Bakery Hotel Cantonese Restaurant \n",
"13 Bar Vietnamese Restaurant Plaza \n",
"19 Italian Restaurant Café Park \n",
"\n",
" 9th Most Common Venue 10th Most Common Venue \n",
"0 Art Museum Cosmetics Shop \n",
"4 Greek Restaurant Museum \n",
"11 Hot Dog Joint Fast Food Restaurant \n",
"12 Japanese Restaurant Cambodian Restaurant \n",
"13 Bakery Pizza Place \n",
"19 Bookstore Supermarket "
]
},
"execution_count": 25,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"paris_merged.loc[paris_merged[\"Cluster Labels\"] == 3, paris_merged.columns[[1] + list(range(5, paris_merged.shape[1]))]]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Cluster 4 has six Neighborhoods consisting of mainly restauration services, touristic sites and few hotels. Hotels could be a great investment in this cluster. other posiible investments are shopping centers, retails shops, banks, etc."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Cluster 5: Orange (west of Paris)"
]
},
{
"cell_type": "code",
"execution_count": 26,
"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>1st Most Common Venue</th>\n",
" <th>2nd Most Common Venue</th>\n",
" <th>3rd Most Common Venue</th>\n",
" <th>4th Most Common Venue</th>\n",
" <th>5th Most Common Venue</th>\n",
" <th>6th Most Common Venue</th>\n",
" <th>7th Most Common Venue</th>\n",
" <th>8th Most Common Venue</th>\n",
" <th>9th Most Common Venue</th>\n",
" <th>10th Most Common Venue</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>6</th>\n",
" <td>Palais-Bourbon</td>\n",
" <td>French Restaurant</td>\n",
" <td>Hotel</td>\n",
" <td>Plaza</td>\n",
" <td>Italian Restaurant</td>\n",
" <td>Café</td>\n",
" <td>Cocktail Bar</td>\n",
" <td>History Museum</td>\n",
" <td>Historic Site</td>\n",
" <td>Ice Cream Shop</td>\n",
" <td>Bar</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Neighborhood 1st Most Common Venue 2nd Most Common Venue \\\n",
"6 Palais-Bourbon French Restaurant Hotel \n",
"\n",
" 3rd Most Common Venue 4th Most Common Venue 5th Most Common Venue \\\n",
"6 Plaza Italian Restaurant Café \n",
"\n",
" 6th Most Common Venue 7th Most Common Venue 8th Most Common Venue \\\n",
"6 Cocktail Bar History Museum Historic Site \n",
"\n",
" 9th Most Common Venue 10th Most Common Venue \n",
"6 Ice Cream Shop Bar "
]
},
"execution_count": 26,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"paris_merged.loc[paris_merged[\"Cluster Labels\"] == 4, paris_merged.columns[[1] + list(range(5, paris_merged.shape[1]))]]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Cluster 5 has one Neighborhood mainly consisting of restauration, Hotels and touristic business venues. Additional restaurants, banks and retail shops could be established here."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- Considering that Paris is a touristic city, Hotels, restaurants, Coffee shops, Bakery and Bars dominates most neighbourhoods.\n",
"- In Reuilly neigbourhood, despite enormous touristic potentials, restaurants and hotels seem to absent. This could be a great investment opportunity for an investor\n",
"- Banks also seem not to be very common in most communities this also represent a great investment opportunities."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Conclusion"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Using Business density analysis, lots of opportunities exists to established competitive businesses in various neighborhoods of the city of Paris. This analysis can also be conducted in other cities in the World with adequate venues data in Foursquare. The results of this analysis when combined with other factors will enable improved business locations for sustainability."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"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.6.8"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment