Práctica calificada 6 - Parte II¶

Ejercicio 5¶

  1. Get a polygons map of the lowest administrative unit possible.
  2. Get a table of variables for those units. At least 3 numerical variables.
  3. Preprocess both tables and get them ready for merging.
  4. Do the merging, making the changes needed so that you keep the most rows.
In [145]:
from google.colab import drive
drive.mount('/content/drive')
Drive already mounted at /content/drive; to attempt to forcibly remount, call drive.mount("/content/drive", force_remount=True).
In [146]:
import os
import geopandas as gpd
gpd.list_layers(os.path.join("/content/drive/MyDrive/ICDE/maps/maps","canadaMaps_ESRI_102001.gpkg"))
Out[146]:
name geometry_type
0 border MultiLineString
1 country MultiPolygon
2 cities Point
3 rivers MultiLineString
4 centroid Point
5 airports Point
6 country_GADM MultiPolygon
7 provincias_GADM MultiPolygon
8 municipios_GADM MultiPolygon
9 menor_GADM MultiPolygon
10 indicators MultiPolygon
In [147]:
country_GADM=gpd.read_file(os.path.join("/content/drive/MyDrive/ICDE/maps/maps","canadaMaps_ESRI_102001.gpkg"), layer='country_GADM')
provincias_GADM=gpd.read_file(os.path.join("/content/drive/MyDrive/ICDE/maps/maps","canadaMaps_ESRI_102001.gpkg"), layer='provincias_GADM')
In [148]:
country_GADM
Out[148]:
GID_0 COUNTRY geometry
0 CAN Canada MULTIPOLYGON (((-1994097.1 1323442.596, -19940...
In [149]:
provincias_GADM
Out[149]:
GID_1 GID_0 COUNTRY NAME_1 VARNAME_1 NL_NAME_1 TYPE_1 ENGTYPE_1 CC_1 HASC_1 ISO_1 geometry
0 CAN.1_1 CAN Canada Alberta NA NA Province Province 48 CA.AB CA-AB MULTIPOLYGON (((-1191696.513 1131094.24, -1193...
1 CAN.2_1 CAN Canada British Columbia Colombie britannique|New Caledon NA Province Province 59 CA.BC CA-BC MULTIPOLYGON (((-1994216.432 1323427.567, -199...
2 CAN.3_1 CAN Canada Manitoba NA NA Province Province 46 CA.MB CA-MB MULTIPOLYGON (((-225729.524 989985.252, -22714...
3 CAN.4_1 CAN Canada New Brunswick Nouveau-Brunswick|Acadia NA Province Province 13 CA.NB CA-NB MULTIPOLYGON (((2280813.977 989844.48, 2280788...
4 CAN.5_1 CAN Canada Newfoundland and Labrador Newfoundland|Terre-Neuve|Terre-N NA Province Province 10 CA.NF CA-NL MULTIPOLYGON (((3062487.374 1723165.753, 30624...
5 CAN.6_1 CAN Canada Northwest Territories Territoires du Nord-Ouest NA Territoire Territory 61 CA.NT CA-NT MULTIPOLYGON (((-932976.987 3668489.676, -9330...
6 CAN.7_1 CAN Canada Nova Scotia Acadia|Nouvelle-Écosse NA Province Province 12 CA.NS CA-NS MULTIPOLYGON (((2419990.709 926493.096, 242000...
7 CAN.8_1 CAN Canada Nunavut NA NA Territoire Territory 62 CA.NU CA-NU MULTIPOLYGON (((1581589.008 2742840.281, 15815...
8 CAN.9_1 CAN Canada Ontario Upper Canada NA Province Province 35 CA.ON CA-ON MULTIPOLYGON (((1409005.46 492629.458, 1408574...
9 CAN.10_1 CAN Canada Prince Edward Island Île de Saint-Jean|Île du Prince- NA Province Province 11 CA.PE CA-PE MULTIPOLYGON (((2505095.555 1289997.862, 25051...
10 CAN.11_1 CAN Canada Québec Lower Canada NA Province Province 24 CA.QC NA MULTIPOLYGON (((1678607.031 812858.207, 167861...
11 CAN.12_1 CAN Canada Saskatchewan NA NA Province Province 47 CA.SK CA-SK MULTIPOLYGON (((-479648.471 1008211.632, -4796...
12 CAN.13_1 CAN Canada Yukon Yukon Territory|Territoire du Yu NA Territoire Territory 60 CA.YT CA-YT MULTIPOLYGON (((-1485495.114 2531187.928, -148...

IDH

In [150]:
import pandas as pd
linkIDH="https://en.wikipedia.org/wiki/List_of_Canadian_provinces_and_territories_by_Human_Development_Index"
IDH=pd.read_html(linkIDH)[0]
IDH
Out[150]:
Rank Province or territory HDI (2022)[1]
0 1 Alberta 0.947
1 2 British Columbia 0.946
2 3 Ontario 0.942
3 — Canada (average) 0.935
4 4 Prince Edward Island 0.929
5 4 Northwest Territories 0.929
6 4 Yukon 0.929
7 4 Nunavut 0.929
8 8 Quebec 0.926
9 9 Saskatchewan 0.920
10 10 Nova Scotia 0.909
11 11 Manitoba 0.907
12 12 New Brunswick 0.904
13 13 Newfoundland and Labrador 0.901
In [151]:
IDH.drop(columns=['Rank'], inplace=True)
IDH.drop(index=3, inplace=True)
IDH.reset_index(drop=True, inplace=True)
IDH.rename(columns={'HDI (2022)[1]':'IDH_2022',"Province or territory":"PROVINCIA"}, inplace=True)
IDH['PROVINCIA']=IDH.PROVINCIA.str.upper()
IDH
Out[151]:
PROVINCIA IDH_2022
0 ALBERTA 0.947
1 BRITISH COLUMBIA 0.946
2 ONTARIO 0.942
3 PRINCE EDWARD ISLAND 0.929
4 NORTHWEST TERRITORIES 0.929
5 YUKON 0.929
6 NUNAVUT 0.929
7 QUEBEC 0.926
8 SASKATCHEWAN 0.920
9 NOVA SCOTIA 0.909
10 MANITOBA 0.907
11 NEW BRUNSWICK 0.904
12 NEWFOUNDLAND AND LABRADOR 0.901
In [152]:
IDH.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 13 entries, 0 to 12
Data columns (total 2 columns):
 #   Column     Non-Null Count  Dtype  
---  ------     --------------  -----  
 0   PROVINCIA  13 non-null     object 
 1   IDH_2022   13 non-null     float64
dtypes: float64(1), object(1)
memory usage: 340.0+ bytes

PBI

In [153]:
linkPBI="https://en.wikipedia.org/wiki/List_of_Canadian_provinces_and_territories_by_gross_domestic_product"
PBI=pd.read_html(linkPBI)[0]      # se tendrá que trabjar con GDP per capita
PBI
Out[153]:
Province or territory GDP (million CAD, 2023) Share of national GDP (%, 2023) Population (July 1, 2023) GDP per capita (CAD, 2023) Market income per capita (CAD, 2022)
0 Canada 2933810 100.00 40083484 73192 39741
1 Alberta 452410 15.42 4684514 96576 43434
2 British Columbia 409881 13.97 5531553 74099 42094
3 Manitoba 91872 3.13 1454743 63153 33057
4 Newfoundland and Labrador 38959 1.33 538907 72293 33871
5 New Brunswick 47035 1.60 832190 56520 32145
6 Northwest Territories 5478 0.19 44681 122602 47470
7 Nova Scotia 59574 2.03 1056486 56389 33866
8 Nunavut 4825 0.16 40700 118550 29475
9 Ontario 1119545 38.16 15623207 71659 40940
10 Prince Edward Island 9924 0.34 173713 57129 32329
11 Quebec 579460 19.75 8848020 65490 37819
12 Saskatchewan 109702 3.74 1209307 90715 35744
13 Yukon 4330 0.15 45463 95242 48232
In [154]:
PBI.drop(columns=["GDP (million CAD, 2023)","Share of national GDP (%, 2023)","Market income per capita (CAD, 2022)"], inplace=True)
PBI.drop(index=0, inplace=True)
PBI.reset_index(drop=True, inplace=True)
PBI.rename(columns={'Population (July 1, 2023)':'Poblacion',"Province or  territory":"PROVINCIA","GDP per capita (CAD, 2023)":"GDPperCapita_2023"}, inplace=True)
PBI['PROVINCIA']=PBI.PROVINCIA.str.upper()
PBI
Out[154]:
PROVINCIA Poblacion GDPperCapita_2023
0 ALBERTA 4684514 96576
1 BRITISH COLUMBIA 5531553 74099
2 MANITOBA 1454743 63153
3 NEWFOUNDLAND AND LABRADOR 538907 72293
4 NEW BRUNSWICK 832190 56520
5 NORTHWEST TERRITORIES 44681 122602
6 NOVA SCOTIA 1056486 56389
7 NUNAVUT 40700 118550
8 ONTARIO 15623207 71659
9 PRINCE EDWARD ISLAND 173713 57129
10 QUEBEC 8848020 65490
11 SASKATCHEWAN 1209307 90715
12 YUKON 45463 95242

homicide rate

In [155]:
linkHomRate="https://en.wikipedia.org/wiki/List_of_Canadian_provinces_and_territories_by_homicide_rate"
HomRate=pd.read_html(linkHomRate)[0]
HomRate
Out[155]:
Province/territory 1990 2000 2010 2015 2016 2017 2018 2019 2020 2021 2022 2023 2015 –2023
0 Ontario 1.77 1.35 1.44 1.27 1.48 1.41 1.90 1.74 1.65 1.91 1.93 1.68 1.66
1 Quebec 2.63 2.00 1.08 0.97 0.81 1.12 1.00 0.92 1.02 1.05 1.28 1.14 1.03
2 British Columbia 3.34 2.10 1.86 2.01 1.85 2.45 1.83 1.78 1.93 2.39 2.89 2.23 2.15
3 Alberta 3.20 1.96 2.09 3.21 2.76 2.81 1.93 2.30 3.24 2.69 2.64 2.45 2.67
4 Manitoba 3.44 2.61 3.69 3.71 3.27 3.52 4.07 5.40 4.49 4.45 6.30 5.09 4.48
5 Saskatchewan 3.57 2.58 3.23 4.10 5.02 3.31 3.03 4.72 5.48 6.08 6.19 4.88 4.76
6 Nova Scotia 0.88 1.71 2.34 1.28 1.38 2.21 1.14 0.61 3.74[n 1] 2.30 1.85 1.32 1.86
7 New Brunswick 1.49 1.33 1.20 1.45 1.44 1.30 1.69 2.19 1.79 1.39 1.85 1.08 1.58
8 Newfoundland and Labrador 0.00 1.14 0.77 0.57 1.51 0.76 0.38 0.95 0.76 1.52 0.56 1.49 0.94
9 Prince Edward Island 0.77 2.20 0.00 0.69 0.00 1.34 0.00 1.28 0.63 0.62 0.00 0.58 0.72
10 Northwest Territories 20.40 2.47 2.31 13.56 6.72 4.48 13.47 4.50 13.48 2.24 6.71 13.34 7.32
11 Yukon 3.60 6.57 2.89 2.65 10.38 20.24 7.43 2.43 0.00 9.31 4.56 8.89 7.32
12 Nunavut NaN 10.91 17.99 5.48 2.70 15.93 20.88 18.02 7.60 4.99 2.47 4.92 9.22
In [156]:
HOMRATE=HomRate.loc[:,["Province/territory","2023"]]
HOMRATE
Out[156]:
Province/territory 2023
0 Ontario 1.68
1 Quebec 1.14
2 British Columbia 2.23
3 Alberta 2.45
4 Manitoba 5.09
5 Saskatchewan 4.88
6 Nova Scotia 1.32
7 New Brunswick 1.08
8 Newfoundland and Labrador 1.49
9 Prince Edward Island 0.58
10 Northwest Territories 13.34
11 Yukon 8.89
12 Nunavut 4.92
In [157]:
HOMRATE.rename(columns={'Province/territory':'PROVINCIA',"2023":"HomicideRate_2023"}, inplace=True)
HOMRATE['PROVINCIA']=HOMRATE.PROVINCIA.str.upper()
HOMRATE
Out[157]:
PROVINCIA HomicideRate_2023
0 ONTARIO 1.68
1 QUEBEC 1.14
2 BRITISH COLUMBIA 2.23
3 ALBERTA 2.45
4 MANITOBA 5.09
5 SASKATCHEWAN 4.88
6 NOVA SCOTIA 1.32
7 NEW BRUNSWICK 1.08
8 NEWFOUNDLAND AND LABRADOR 1.49
9 PRINCE EDWARD ISLAND 0.58
10 NORTHWEST TERRITORIES 13.34
11 YUKON 8.89
12 NUNAVUT 4.92
In [158]:
# se hace merge entre los 3 DF
IDH_PBI=pd.merge(IDH,PBI, on='PROVINCIA')
dataVariables=pd.merge(IDH_PBI,HOMRATE, on='PROVINCIA')
dataVariables
Out[158]:
PROVINCIA IDH_2022 Poblacion GDPperCapita_2023 HomicideRate_2023
0 ALBERTA 0.947 4684514 96576 2.45
1 BRITISH COLUMBIA 0.946 5531553 74099 2.23
2 ONTARIO 0.942 15623207 71659 1.68
3 PRINCE EDWARD ISLAND 0.929 173713 57129 0.58
4 NORTHWEST TERRITORIES 0.929 44681 122602 13.34
5 YUKON 0.929 45463 95242 8.89
6 NUNAVUT 0.929 40700 118550 4.92
7 QUEBEC 0.926 8848020 65490 1.14
8 SASKATCHEWAN 0.920 1209307 90715 4.88
9 NOVA SCOTIA 0.909 1056486 56389 1.32
10 MANITOBA 0.907 1454743 63153 5.09
11 NEW BRUNSWICK 0.904 832190 56520 1.08
12 NEWFOUNDLAND AND LABRADOR 0.901 538907 72293 1.49
In [159]:
provincias_GADM
Out[159]:
GID_1 GID_0 COUNTRY NAME_1 VARNAME_1 NL_NAME_1 TYPE_1 ENGTYPE_1 CC_1 HASC_1 ISO_1 geometry
0 CAN.1_1 CAN Canada Alberta NA NA Province Province 48 CA.AB CA-AB MULTIPOLYGON (((-1191696.513 1131094.24, -1193...
1 CAN.2_1 CAN Canada British Columbia Colombie britannique|New Caledon NA Province Province 59 CA.BC CA-BC MULTIPOLYGON (((-1994216.432 1323427.567, -199...
2 CAN.3_1 CAN Canada Manitoba NA NA Province Province 46 CA.MB CA-MB MULTIPOLYGON (((-225729.524 989985.252, -22714...
3 CAN.4_1 CAN Canada New Brunswick Nouveau-Brunswick|Acadia NA Province Province 13 CA.NB CA-NB MULTIPOLYGON (((2280813.977 989844.48, 2280788...
4 CAN.5_1 CAN Canada Newfoundland and Labrador Newfoundland|Terre-Neuve|Terre-N NA Province Province 10 CA.NF CA-NL MULTIPOLYGON (((3062487.374 1723165.753, 30624...
5 CAN.6_1 CAN Canada Northwest Territories Territoires du Nord-Ouest NA Territoire Territory 61 CA.NT CA-NT MULTIPOLYGON (((-932976.987 3668489.676, -9330...
6 CAN.7_1 CAN Canada Nova Scotia Acadia|Nouvelle-Écosse NA Province Province 12 CA.NS CA-NS MULTIPOLYGON (((2419990.709 926493.096, 242000...
7 CAN.8_1 CAN Canada Nunavut NA NA Territoire Territory 62 CA.NU CA-NU MULTIPOLYGON (((1581589.008 2742840.281, 15815...
8 CAN.9_1 CAN Canada Ontario Upper Canada NA Province Province 35 CA.ON CA-ON MULTIPOLYGON (((1409005.46 492629.458, 1408574...
9 CAN.10_1 CAN Canada Prince Edward Island Île de Saint-Jean|Île du Prince- NA Province Province 11 CA.PE CA-PE MULTIPOLYGON (((2505095.555 1289997.862, 25051...
10 CAN.11_1 CAN Canada Québec Lower Canada NA Province Province 24 CA.QC NA MULTIPOLYGON (((1678607.031 812858.207, 167861...
11 CAN.12_1 CAN Canada Saskatchewan NA NA Province Province 47 CA.SK CA-SK MULTIPOLYGON (((-479648.471 1008211.632, -4796...
12 CAN.13_1 CAN Canada Yukon Yukon Territory|Territoire du Yu NA Territoire Territory 60 CA.YT CA-YT MULTIPOLYGON (((-1485495.114 2531187.928, -148...
In [160]:
provincias_GADM.columns.to_list()
Out[160]:
['GID_1',
 'GID_0',
 'COUNTRY',
 'NAME_1',
 'VARNAME_1',
 'NL_NAME_1',
 'TYPE_1',
 'ENGTYPE_1',
 'CC_1',
 'HASC_1',
 'ISO_1',
 'geometry']
In [161]:
# nos quedamos con las columnas importantes
provinciasGeometria=provincias_GADM.loc[:,['COUNTRY','NAME_1','geometry']]
provinciasGeometria
Out[161]:
COUNTRY NAME_1 geometry
0 Canada Alberta MULTIPOLYGON (((-1191696.513 1131094.24, -1193...
1 Canada British Columbia MULTIPOLYGON (((-1994216.432 1323427.567, -199...
2 Canada Manitoba MULTIPOLYGON (((-225729.524 989985.252, -22714...
3 Canada New Brunswick MULTIPOLYGON (((2280813.977 989844.48, 2280788...
4 Canada Newfoundland and Labrador MULTIPOLYGON (((3062487.374 1723165.753, 30624...
5 Canada Northwest Territories MULTIPOLYGON (((-932976.987 3668489.676, -9330...
6 Canada Nova Scotia MULTIPOLYGON (((2419990.709 926493.096, 242000...
7 Canada Nunavut MULTIPOLYGON (((1581589.008 2742840.281, 15815...
8 Canada Ontario MULTIPOLYGON (((1409005.46 492629.458, 1408574...
9 Canada Prince Edward Island MULTIPOLYGON (((2505095.555 1289997.862, 25051...
10 Canada Québec MULTIPOLYGON (((1678607.031 812858.207, 167861...
11 Canada Saskatchewan MULTIPOLYGON (((-479648.471 1008211.632, -4796...
12 Canada Yukon MULTIPOLYGON (((-1485495.114 2531187.928, -148...
In [162]:
provinciasGeometria.rename(columns={"NAME_1":"PROVINCIA"}, inplace=True)
provinciasGeometria['PROVINCIA']=provinciasGeometria.PROVINCIA.str.upper()
provinciasGeometria['COUNTRY']=provinciasGeometria.COUNTRY.str.upper()
provinciasGeometria.loc[10,"PROVINCIA"]='QUEBEC'
provinciasGeometria
Out[162]:
COUNTRY PROVINCIA geometry
0 CANADA ALBERTA MULTIPOLYGON (((-1191696.513 1131094.24, -1193...
1 CANADA BRITISH COLUMBIA MULTIPOLYGON (((-1994216.432 1323427.567, -199...
2 CANADA MANITOBA MULTIPOLYGON (((-225729.524 989985.252, -22714...
3 CANADA NEW BRUNSWICK MULTIPOLYGON (((2280813.977 989844.48, 2280788...
4 CANADA NEWFOUNDLAND AND LABRADOR MULTIPOLYGON (((3062487.374 1723165.753, 30624...
5 CANADA NORTHWEST TERRITORIES MULTIPOLYGON (((-932976.987 3668489.676, -9330...
6 CANADA NOVA SCOTIA MULTIPOLYGON (((2419990.709 926493.096, 242000...
7 CANADA NUNAVUT MULTIPOLYGON (((1581589.008 2742840.281, 15815...
8 CANADA ONTARIO MULTIPOLYGON (((1409005.46 492629.458, 1408574...
9 CANADA PRINCE EDWARD ISLAND MULTIPOLYGON (((2505095.555 1289997.862, 25051...
10 CANADA QUEBEC MULTIPOLYGON (((1678607.031 812858.207, 167861...
11 CANADA SASKATCHEWAN MULTIPOLYGON (((-479648.471 1008211.632, -4796...
12 CANADA YUKON MULTIPOLYGON (((-1485495.114 2531187.928, -148...
In [163]:
# finalmente se hace merge para tener la geometría y las variables en un solo GDF
data=pd.merge(provinciasGeometria,dataVariables, on='PROVINCIA')
data
Out[163]:
COUNTRY PROVINCIA geometry IDH_2022 Poblacion GDPperCapita_2023 HomicideRate_2023
0 CANADA ALBERTA MULTIPOLYGON (((-1191696.513 1131094.24, -1193... 0.947 4684514 96576 2.45
1 CANADA BRITISH COLUMBIA MULTIPOLYGON (((-1994216.432 1323427.567, -199... 0.946 5531553 74099 2.23
2 CANADA MANITOBA MULTIPOLYGON (((-225729.524 989985.252, -22714... 0.907 1454743 63153 5.09
3 CANADA NEW BRUNSWICK MULTIPOLYGON (((2280813.977 989844.48, 2280788... 0.904 832190 56520 1.08
4 CANADA NEWFOUNDLAND AND LABRADOR MULTIPOLYGON (((3062487.374 1723165.753, 30624... 0.901 538907 72293 1.49
5 CANADA NORTHWEST TERRITORIES MULTIPOLYGON (((-932976.987 3668489.676, -9330... 0.929 44681 122602 13.34
6 CANADA NOVA SCOTIA MULTIPOLYGON (((2419990.709 926493.096, 242000... 0.909 1056486 56389 1.32
7 CANADA NUNAVUT MULTIPOLYGON (((1581589.008 2742840.281, 15815... 0.929 40700 118550 4.92
8 CANADA ONTARIO MULTIPOLYGON (((1409005.46 492629.458, 1408574... 0.942 15623207 71659 1.68
9 CANADA PRINCE EDWARD ISLAND MULTIPOLYGON (((2505095.555 1289997.862, 25051... 0.929 173713 57129 0.58
10 CANADA QUEBEC MULTIPOLYGON (((1678607.031 812858.207, 167861... 0.926 8848020 65490 1.14
11 CANADA SASKATCHEWAN MULTIPOLYGON (((-479648.471 1008211.632, -4796... 0.920 1209307 90715 4.88
12 CANADA YUKON MULTIPOLYGON (((-1485495.114 2531187.928, -148... 0.929 45463 95242 8.89

Ejercicio 6¶

Compute the neighbors of the capital city of your country. Plot the results for each of the options.

In [164]:
# buscar vecinos de las 3 maneras, pero luego decido con cuál quedarme
In [165]:
#rojo es capital y amarillo son distritos
In [166]:
base=data.plot()
data[data.PROVINCIA=='ONTARIO'].plot(ax=base, color='red')
Out[166]:
<Axes: >
No description has been provided for this image
In [167]:
!pip install folium matplotlib mapclassify
Requirement already satisfied: folium in /usr/local/lib/python3.11/dist-packages (0.19.7)
Requirement already satisfied: matplotlib in /usr/local/lib/python3.11/dist-packages (3.10.0)
Requirement already satisfied: mapclassify in /usr/local/lib/python3.11/dist-packages (2.9.0)
Requirement already satisfied: branca>=0.6.0 in /usr/local/lib/python3.11/dist-packages (from folium) (0.8.1)
Requirement already satisfied: jinja2>=2.9 in /usr/local/lib/python3.11/dist-packages (from folium) (3.1.6)
Requirement already satisfied: numpy in /usr/local/lib/python3.11/dist-packages (from folium) (2.0.2)
Requirement already satisfied: requests in /usr/local/lib/python3.11/dist-packages (from folium) (2.32.3)
Requirement already satisfied: xyzservices in /usr/local/lib/python3.11/dist-packages (from folium) (2025.4.0)
Requirement already satisfied: contourpy>=1.0.1 in /usr/local/lib/python3.11/dist-packages (from matplotlib) (1.3.2)
Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.11/dist-packages (from matplotlib) (0.12.1)
Requirement already satisfied: fonttools>=4.22.0 in /usr/local/lib/python3.11/dist-packages (from matplotlib) (4.58.4)
Requirement already satisfied: kiwisolver>=1.3.1 in /usr/local/lib/python3.11/dist-packages (from matplotlib) (1.4.8)
Requirement already satisfied: packaging>=20.0 in /usr/local/lib/python3.11/dist-packages (from matplotlib) (24.2)
Requirement already satisfied: pillow>=8 in /usr/local/lib/python3.11/dist-packages (from matplotlib) (11.2.1)
Requirement already satisfied: pyparsing>=2.3.1 in /usr/local/lib/python3.11/dist-packages (from matplotlib) (3.2.3)
Requirement already satisfied: python-dateutil>=2.7 in /usr/local/lib/python3.11/dist-packages (from matplotlib) (2.9.0.post0)
Requirement already satisfied: networkx>=3.2 in /usr/local/lib/python3.11/dist-packages (from mapclassify) (3.5)
Requirement already satisfied: pandas>=2.1 in /usr/local/lib/python3.11/dist-packages (from mapclassify) (2.2.2)
Requirement already satisfied: scikit-learn>=1.4 in /usr/local/lib/python3.11/dist-packages (from mapclassify) (1.6.1)
Requirement already satisfied: scipy>=1.12 in /usr/local/lib/python3.11/dist-packages (from mapclassify) (1.15.3)
Requirement already satisfied: MarkupSafe>=2.0 in /usr/local/lib/python3.11/dist-packages (from jinja2>=2.9->folium) (3.0.2)
Requirement already satisfied: pytz>=2020.1 in /usr/local/lib/python3.11/dist-packages (from pandas>=2.1->mapclassify) (2025.2)
Requirement already satisfied: tzdata>=2022.7 in /usr/local/lib/python3.11/dist-packages (from pandas>=2.1->mapclassify) (2025.2)
Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.11/dist-packages (from python-dateutil>=2.7->matplotlib) (1.17.0)
Requirement already satisfied: joblib>=1.2.0 in /usr/local/lib/python3.11/dist-packages (from scikit-learn>=1.4->mapclassify) (1.5.1)
Requirement already satisfied: threadpoolctl>=3.1.0 in /usr/local/lib/python3.11/dist-packages (from scikit-learn>=1.4->mapclassify) (3.6.0)
Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.11/dist-packages (from requests->folium) (3.4.2)
Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.11/dist-packages (from requests->folium) (3.10)
Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.11/dist-packages (from requests->folium) (2.4.0)
Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.11/dist-packages (from requests->folium) (2025.6.15)
In [168]:
menor_GADM=gpd.read_file(os.path.join("/content/drive/MyDrive/ICDE/maps/maps","canadaMaps_ESRI_102001.gpkg"), layer='menor_GADM')
menor_GADM.head()
Out[168]:
GID_3 GID_0 COUNTRY GID_1 NAME_1 NL_NAME_1 GID_2 NAME_2 NL_NAME_2 NAME_3 VARNAME_3 NL_NAME_3 TYPE_3 ENGTYPE_3 CC_3 HASC_3 geometry
0 CAN.1.11.1_1 CAN Canada CAN.1_1 Alberta NA CAN.1.11_1 Division No. 1 NA Bow Island NA NA Town Town NA NA MULTIPOLYGON (((-1095252.637 1208455.549, -109...
1 CAN.1.11.2_1 CAN Canada CAN.1_1 Alberta NA CAN.1.11_1 Division No. 1 NA Burdett NA NA Village Village NA NA MULTIPOLYGON (((-1106734.051 1207041.712, -110...
2 CAN.1.11.3_1 CAN Canada CAN.1_1 Alberta NA CAN.1.11_1 Division No. 1 NA Cypress County NA NA Municipal District Municipal District NA NA MULTIPOLYGON (((-1114033.57 1214677.478, -1114...
3 CAN.1.11.4_1 CAN Canada CAN.1_1 Alberta NA CAN.1.11_1 Division No. 1 NA Foremost NA NA Village Village NA NA MULTIPOLYGON (((-1110213.091 1166590.676, -111...
4 CAN.1.11.5_1 CAN Canada CAN.1_1 Alberta NA CAN.1.11_1 Division No. 1 NA Forty Mile County No. 8 NA NA County Municipality County Municipality NA NA MULTIPOLYGON (((-1114033.57 1214677.478, -1113...
In [169]:
# en este caso, se trabajará con la capa con las geometrías más pequeñas, no con el GDF trabajado en la anterior actividad
from libpysal.weights import Queen, Rook, KNN

# rook
w_rook = Rook.from_dataframe(menor_GADM,use_index=False)
In [170]:
w_queen = Queen.from_dataframe(menor_GADM,use_index=False)
In [171]:
w_knn20 = KNN.from_dataframe(menor_GADM, k=20)
In [172]:
menor_GADM[menor_GADM.NAME_2=="Ottawa"]
Out[172]:
GID_3 GID_0 COUNTRY GID_1 NAME_1 NL_NAME_1 GID_2 NAME_2 NL_NAME_2 NAME_3 VARNAME_3 NL_NAME_3 TYPE_3 ENGTYPE_3 CC_3 HASC_3 geometry
2713 CAN.9.35.1_1 CAN Canada CAN.9_1 Ontario NA CAN.9.35_1 Ottawa NA Ottawa NA NA Cité City NA NA MULTIPOLYGON (((1576105.437 788452.556, 157618...

rook

In [173]:
menor_GADM.iloc[w_rook.neighbors[2713] ,]
Out[173]:
GID_3 GID_0 COUNTRY GID_1 NAME_1 NL_NAME_1 GID_2 NAME_2 NL_NAME_2 NAME_3 VARNAME_3 NL_NAME_3 TYPE_3 ENGTYPE_3 CC_3 HASC_3 geometry
2819 CAN.9.44.13_1 CAN Canada CAN.9_1 Ontario NA CAN.9.44_1 Renfrew NA McNab/Braeside NA NA Township Township NA NA MULTIPOLYGON (((1534436.789 813992.934, 153416...
2628 CAN.9.27.9_1 CAN Canada CAN.9_1 Ontario NA CAN.9.27_1 Leeds and Grenville NA Merrickville-Wolford NA NA Village Village NA NA MULTIPOLYGON (((1578566.446 768358.064, 157863...
2629 CAN.9.27.10_1 CAN Canada CAN.9_1 Ontario NA CAN.9.27_1 Leeds and Grenville NA North Grenville NA NA Township Township NA NA MULTIPOLYGON (((1605927.213 775203.269, 160548...
4298 CAN.11.85.9_1 CAN Canada CAN.11_1 Québec NA CAN.11.85_1 Papineau NA Lochaber-Partie-Ouest NA NA Municipalité De Canton Canton Municipality NA NA MULTIPOLYGON (((1607168.778 851571.936, 160696...
3346 CAN.11.19.1_1 CAN Canada CAN.11_1 Québec NA CAN.11.19_1 Communauté-Urbaine-de-l'Outaouai NA Aylmer NA NA Ville Ville NA NA MULTIPOLYGON (((1580023.424 828702.304, 157996...
3348 CAN.11.19.3_1 CAN Canada CAN.11_1 Québec NA CAN.11.19_1 Communauté-Urbaine-de-l'Outaouai NA Gatineau NA NA Ville Ville NA NA MULTIPOLYGON (((1594697.151 843000.144, 159457...
3349 CAN.11.19.4_1 CAN Canada CAN.11_1 Québec NA CAN.11.19_1 Communauté-Urbaine-de-l'Outaouai NA Hull NA NA Ville Ville NA NA MULTIPOLYGON (((1583424.937 834159.215, 158329...
3350 CAN.11.19.5_1 CAN Canada CAN.11_1 Québec NA CAN.11.19_1 Communauté-Urbaine-de-l'Outaouai NA Masson-Angers NA NA Ville Ville NA NA MULTIPOLYGON (((1606967.254 851487.278, 160681...
2776 CAN.9.41.4_1 CAN Canada CAN.9_1 Ontario NA CAN.9.41_1 Prescott and Russell NA Clarence-Rockland NA NA Cité City NA NA MULTIPOLYGON (((1620148.048 835829.62, 1620096...
2779 CAN.9.41.7_1 CAN Canada CAN.9_1 Ontario NA CAN.9.41_1 Prescott and Russell NA Russell NA NA Township Township NA NA MULTIPOLYGON (((1618149.828 814194.153, 161786...
2780 CAN.9.41.8_1 CAN Canada CAN.9_1 Ontario NA CAN.9.41_1 Prescott and Russell NA The Nation Municipality NA NA Township Township NA NA MULTIPOLYGON (((1618798.831 834437.131, 161879...
2848 CAN.9.46.3_1 CAN Canada CAN.9_1 Ontario NA CAN.9.46_1 Stormont, Dundas and Glengarry NA North Dundas NA NA Township Township NA NA MULTIPOLYGON (((1615543.723 787415.214, 161553...
2616 CAN.9.26.6_1 CAN Canada CAN.9_1 Ontario NA CAN.9.26_1 Lanark NA Mississippi Mills NA NA Town Town NA NA MULTIPOLYGON (((1562965.857 798093.91, 1562154...
3951 CAN.11.63.6_1 CAN Canada CAN.11_1 Québec NA CAN.11.63_1 Les Collines-de-l'Outaouais NA Pontiac NA NA Municipalité Municipality NA NA MULTIPOLYGON (((1569848.222 824350.784, 156983...
2612 CAN.9.26.2_1 CAN Canada CAN.9_1 Ontario NA CAN.9.26_1 Lanark NA Beckwith NA NA Township Township NA NA MULTIPOLYGON (((1558157.764 790253.978, 155845...
2808 CAN.9.44.2_1 CAN Canada CAN.9_1 Ontario NA CAN.9.44_1 Renfrew NA Arnprior NA NA Town Town NA NA MULTIPOLYGON (((1534795.84 814658.656, 1534728...
2617 CAN.9.26.7_1 CAN Canada CAN.9_1 Ontario NA CAN.9.26_1 Lanark NA Montague NA NA Township Township NA NA MULTIPOLYGON (((1568113.605 775753.877, 156811...
In [174]:
# para metodo rook
base=menor_GADM.iloc[w_rook.neighbors[2713],].plot(facecolor="yellow",edgecolor='k')
menor_GADM.loc[menor_GADM.NAME_2=='Ottawa'].plot(ax=base,facecolor="red")
Out[174]:
<Axes: >
No description has been provided for this image

queen

In [175]:
menor_GADM.iloc[w_queen.neighbors[2713] ,]
Out[175]:
GID_3 GID_0 COUNTRY GID_1 NAME_1 NL_NAME_1 GID_2 NAME_2 NL_NAME_2 NAME_3 VARNAME_3 NL_NAME_3 TYPE_3 ENGTYPE_3 CC_3 HASC_3 geometry
2819 CAN.9.44.13_1 CAN Canada CAN.9_1 Ontario NA CAN.9.44_1 Renfrew NA McNab/Braeside NA NA Township Township NA NA MULTIPOLYGON (((1534436.789 813992.934, 153416...
2628 CAN.9.27.9_1 CAN Canada CAN.9_1 Ontario NA CAN.9.27_1 Leeds and Grenville NA Merrickville-Wolford NA NA Village Village NA NA MULTIPOLYGON (((1578566.446 768358.064, 157863...
2629 CAN.9.27.10_1 CAN Canada CAN.9_1 Ontario NA CAN.9.27_1 Leeds and Grenville NA North Grenville NA NA Township Township NA NA MULTIPOLYGON (((1605927.213 775203.269, 160548...
4298 CAN.11.85.9_1 CAN Canada CAN.11_1 Québec NA CAN.11.85_1 Papineau NA Lochaber-Partie-Ouest NA NA Municipalité De Canton Canton Municipality NA NA MULTIPOLYGON (((1607168.778 851571.936, 160696...
3346 CAN.11.19.1_1 CAN Canada CAN.11_1 Québec NA CAN.11.19_1 Communauté-Urbaine-de-l'Outaouai NA Aylmer NA NA Ville Ville NA NA MULTIPOLYGON (((1580023.424 828702.304, 157996...
3348 CAN.11.19.3_1 CAN Canada CAN.11_1 Québec NA CAN.11.19_1 Communauté-Urbaine-de-l'Outaouai NA Gatineau NA NA Ville Ville NA NA MULTIPOLYGON (((1594697.151 843000.144, 159457...
3349 CAN.11.19.4_1 CAN Canada CAN.11_1 Québec NA CAN.11.19_1 Communauté-Urbaine-de-l'Outaouai NA Hull NA NA Ville Ville NA NA MULTIPOLYGON (((1583424.937 834159.215, 158329...
3350 CAN.11.19.5_1 CAN Canada CAN.11_1 Québec NA CAN.11.19_1 Communauté-Urbaine-de-l'Outaouai NA Masson-Angers NA NA Ville Ville NA NA MULTIPOLYGON (((1606967.254 851487.278, 160681...
2776 CAN.9.41.4_1 CAN Canada CAN.9_1 Ontario NA CAN.9.41_1 Prescott and Russell NA Clarence-Rockland NA NA Cité City NA NA MULTIPOLYGON (((1620148.048 835829.62, 1620096...
4315 CAN.11.86.2_1 CAN Canada CAN.11_1 Québec NA CAN.11.86_1 Pontiac NA Bristol NA NA Municipalité De Canton Canton Municipality NA NA MULTIPOLYGON (((1537464.461 821648.713, 153672...
2780 CAN.9.41.8_1 CAN Canada CAN.9_1 Ontario NA CAN.9.41_1 Prescott and Russell NA The Nation Municipality NA NA Township Township NA NA MULTIPOLYGON (((1618798.831 834437.131, 161879...
2779 CAN.9.41.7_1 CAN Canada CAN.9_1 Ontario NA CAN.9.41_1 Prescott and Russell NA Russell NA NA Township Township NA NA MULTIPOLYGON (((1618149.828 814194.153, 161786...
2848 CAN.9.46.3_1 CAN Canada CAN.9_1 Ontario NA CAN.9.46_1 Stormont, Dundas and Glengarry NA North Dundas NA NA Township Township NA NA MULTIPOLYGON (((1615543.723 787415.214, 161553...
3951 CAN.11.63.6_1 CAN Canada CAN.11_1 Québec NA CAN.11.63_1 Les Collines-de-l'Outaouais NA Pontiac NA NA Municipalité Municipality NA NA MULTIPOLYGON (((1569848.222 824350.784, 156983...
2808 CAN.9.44.2_1 CAN Canada CAN.9_1 Ontario NA CAN.9.44_1 Renfrew NA Arnprior NA NA Town Town NA NA MULTIPOLYGON (((1534795.84 814658.656, 1534728...
2612 CAN.9.26.2_1 CAN Canada CAN.9_1 Ontario NA CAN.9.26_1 Lanark NA Beckwith NA NA Township Township NA NA MULTIPOLYGON (((1558157.764 790253.978, 155845...
2616 CAN.9.26.6_1 CAN Canada CAN.9_1 Ontario NA CAN.9.26_1 Lanark NA Mississippi Mills NA NA Town Town NA NA MULTIPOLYGON (((1562965.857 798093.91, 1562154...
2617 CAN.9.26.7_1 CAN Canada CAN.9_1 Ontario NA CAN.9.26_1 Lanark NA Montague NA NA Township Township NA NA MULTIPOLYGON (((1568113.605 775753.877, 156811...
In [176]:
# para metodo queen
base=menor_GADM.iloc[w_queen.neighbors[2713],].plot(facecolor="yellow",edgecolor='k')
menor_GADM.loc[menor_GADM.NAME_2=='Ottawa'].plot(ax=base,facecolor="red")
Out[176]:
<Axes: >
No description has been provided for this image

knn

In [177]:
menor_GADM.iloc[w_knn20.neighbors[2713] ,]
Out[177]:
GID_3 GID_0 COUNTRY GID_1 NAME_1 NL_NAME_1 GID_2 NAME_2 NL_NAME_2 NAME_3 VARNAME_3 NL_NAME_3 TYPE_3 ENGTYPE_3 CC_3 HASC_3 geometry
3346 CAN.11.19.1_1 CAN Canada CAN.11_1 Québec NA CAN.11.19_1 Communauté-Urbaine-de-l'Outaouai NA Aylmer NA NA Ville Ville NA NA MULTIPOLYGON (((1580023.424 828702.304, 157996...
3349 CAN.11.19.4_1 CAN Canada CAN.11_1 Québec NA CAN.11.19_1 Communauté-Urbaine-de-l'Outaouai NA Hull NA NA Ville Ville NA NA MULTIPOLYGON (((1583424.937 834159.215, 158329...
3348 CAN.11.19.3_1 CAN Canada CAN.11_1 Québec NA CAN.11.19_1 Communauté-Urbaine-de-l'Outaouai NA Gatineau NA NA Ville Ville NA NA MULTIPOLYGON (((1594697.151 843000.144, 159457...
3947 CAN.11.63.2_1 CAN Canada CAN.11_1 Québec NA CAN.11.63_1 Les Collines-de-l'Outaouais NA Chelsea NA NA Municipalité Municipality NA NA MULTIPOLYGON (((1575771.079 832749.821, 157562...
3946 CAN.11.63.1_1 CAN Canada CAN.11_1 Québec NA CAN.11.63_1 Les Collines-de-l'Outaouais NA Cantley NA NA Municipalité Municipality NA NA MULTIPOLYGON (((1580989.538 844883.571, 158067...
2612 CAN.9.26.2_1 CAN Canada CAN.9_1 Ontario NA CAN.9.26_1 Lanark NA Beckwith NA NA Township Township NA NA MULTIPOLYGON (((1558157.764 790253.978, 155845...
2613 CAN.9.26.3_1 CAN Canada CAN.9_1 Ontario NA CAN.9.26_1 Lanark NA Carleton Place NA NA Town Town NA NA MULTIPOLYGON (((1559353.352 792376.267, 155937...
2629 CAN.9.27.10_1 CAN Canada CAN.9_1 Ontario NA CAN.9.27_1 Leeds and Grenville NA North Grenville NA NA Township Township NA NA MULTIPOLYGON (((1605927.213 775203.269, 160548...
2779 CAN.9.41.7_1 CAN Canada CAN.9_1 Ontario NA CAN.9.41_1 Prescott and Russell NA Russell NA NA Township Township NA NA MULTIPOLYGON (((1618149.828 814194.153, 161786...
3350 CAN.11.19.5_1 CAN Canada CAN.11_1 Québec NA CAN.11.19_1 Communauté-Urbaine-de-l'Outaouai NA Masson-Angers NA NA Ville Ville NA NA MULTIPOLYGON (((1606967.254 851487.278, 160681...
2617 CAN.9.26.7_1 CAN Canada CAN.9_1 Ontario NA CAN.9.26_1 Lanark NA Montague NA NA Township Township NA NA MULTIPOLYGON (((1568113.605 775753.877, 156811...
2848 CAN.9.46.3_1 CAN Canada CAN.9_1 Ontario NA CAN.9.46_1 Stormont, Dundas and Glengarry NA North Dundas NA NA Township Township NA NA MULTIPOLYGON (((1615543.723 787415.214, 161553...
3951 CAN.11.63.6_1 CAN Canada CAN.11_1 Québec NA CAN.11.63_1 Les Collines-de-l'Outaouais NA Pontiac NA NA Municipalité Municipality NA NA MULTIPOLYGON (((1569848.222 824350.784, 156983...
2616 CAN.9.26.6_1 CAN Canada CAN.9_1 Ontario NA CAN.9.26_1 Lanark NA Mississippi Mills NA NA Town Town NA NA MULTIPOLYGON (((1562965.857 798093.91, 1562154...
3347 CAN.11.19.2_1 CAN Canada CAN.11_1 Québec NA CAN.11.19_1 Communauté-Urbaine-de-l'Outaouai NA Buckingham NA NA Ville Ville NA NA MULTIPOLYGON (((1601416.46 856388.1, 1601453.0...
3952 CAN.11.63.7_1 CAN Canada CAN.11_1 Québec NA CAN.11.63_1 Les Collines-de-l'Outaouais NA Val-des-Monts NA NA Municipalité Municipality NA NA MULTIPOLYGON (((1591234.317 850923.373, 159077...
3948 CAN.11.63.3_1 CAN Canada CAN.11_1 Québec NA CAN.11.63_1 Les Collines-de-l'Outaouais NA L'Ange-Gardien NA NA Municipalité Municipality NA NA MULTIPOLYGON (((1601416.46 856388.1, 1601352.1...
2619 CAN.9.26.9_1 CAN Canada CAN.9_1 Ontario NA CAN.9.26_1 Lanark NA Smiths Falls NA NA Town Town NA NA MULTIPOLYGON (((1575539.472 769005.2, 1575437....
2808 CAN.9.44.2_1 CAN Canada CAN.9_1 Ontario NA CAN.9.44_1 Renfrew NA Arnprior NA NA Town Town NA NA MULTIPOLYGON (((1534795.84 814658.656, 1534728...
2628 CAN.9.27.9_1 CAN Canada CAN.9_1 Ontario NA CAN.9.27_1 Leeds and Grenville NA Merrickville-Wolford NA NA Village Village NA NA MULTIPOLYGON (((1578566.446 768358.064, 157863...
In [178]:
# para metodo knn
base=menor_GADM.iloc[w_knn20.neighbors[2713] ,].plot(facecolor="yellow",edgecolor='k')
menor_GADM.loc[menor_GADM.NAME_2=='Ottawa'].plot(ax=base,facecolor="red")
Out[178]:
<Axes: >
No description has been provided for this image

Ejercicio 7¶

  1. Compute the Moran's coefficient for one of your three numeric variables.
  2. Make a scatter plot for each variable.
In [179]:
# hacer merge con nivel de contaminacion, # niños en edad escola, etc
# se hace merge con 3 VARIABLES, y solo con una se hace el analisis este de correlacion
In [180]:
pd.DataFrame(*w_knn20.full())
Out[180]:
0 1 2 3 4 5 6 7 8 9 ... 5571 5572 5573 5574 5575 5576 5577 5578 5579 5580
0 0.0 1.0 1.0 1.0 1.0 1.0 1.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
1 1.0 0.0 1.0 1.0 1.0 1.0 1.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
2 1.0 1.0 0.0 1.0 1.0 1.0 1.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
3 1.0 1.0 1.0 0.0 1.0 1.0 1.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
4 1.0 1.0 1.0 1.0 0.0 1.0 1.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
5576 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 1.0 1.0 1.0 1.0 1.0 0.0 1.0 0.0 0.0 0.0
5577 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 1.0 1.0 1.0 1.0 1.0 1.0 0.0 0.0 0.0 0.0
5578 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 1.0 1.0 1.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0
5579 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 1.0 1.0 1.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0
5580 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 1.0 0.0

5581 rows × 5581 columns

In [181]:
w_knn20.transform = 'R'
In [182]:
pd.DataFrame(*w_knn20.full()).sum(axis=1)
Out[182]:
0
0 1.0
1 1.0
2 1.0
3 1.0
4 1.0
... ...
5576 1.0
5577 1.0
5578 1.0
5579 1.0
5580 1.0

5581 rows × 1 columns


In [183]:
!pip install esda
Requirement already satisfied: esda in /usr/local/lib/python3.11/dist-packages (2.7.0)
Requirement already satisfied: geopandas>=0.12 in /usr/local/lib/python3.11/dist-packages (from esda) (1.0.1)
Requirement already satisfied: libpysal>=4.12 in /usr/local/lib/python3.11/dist-packages (from esda) (4.13.0)
Requirement already satisfied: numpy>=1.24 in /usr/local/lib/python3.11/dist-packages (from esda) (2.0.2)
Requirement already satisfied: pandas>1.5 in /usr/local/lib/python3.11/dist-packages (from esda) (2.2.2)
Requirement already satisfied: scikit-learn>=1.2 in /usr/local/lib/python3.11/dist-packages (from esda) (1.6.1)
Requirement already satisfied: scipy>=1.9 in /usr/local/lib/python3.11/dist-packages (from esda) (1.15.3)
Requirement already satisfied: shapely>=2.0 in /usr/local/lib/python3.11/dist-packages (from esda) (2.1.1)
Requirement already satisfied: pyogrio>=0.7.2 in /usr/local/lib/python3.11/dist-packages (from geopandas>=0.12->esda) (0.11.0)
Requirement already satisfied: packaging in /usr/local/lib/python3.11/dist-packages (from geopandas>=0.12->esda) (24.2)
Requirement already satisfied: pyproj>=3.3.0 in /usr/local/lib/python3.11/dist-packages (from geopandas>=0.12->esda) (3.7.1)
Requirement already satisfied: beautifulsoup4>=4.10 in /usr/local/lib/python3.11/dist-packages (from libpysal>=4.12->esda) (4.13.4)
Requirement already satisfied: platformdirs>=2.0.2 in /usr/local/lib/python3.11/dist-packages (from libpysal>=4.12->esda) (4.3.8)
Requirement already satisfied: requests>=2.27 in /usr/local/lib/python3.11/dist-packages (from libpysal>=4.12->esda) (2.32.3)
Requirement already satisfied: python-dateutil>=2.8.2 in /usr/local/lib/python3.11/dist-packages (from pandas>1.5->esda) (2.9.0.post0)
Requirement already satisfied: pytz>=2020.1 in /usr/local/lib/python3.11/dist-packages (from pandas>1.5->esda) (2025.2)
Requirement already satisfied: tzdata>=2022.7 in /usr/local/lib/python3.11/dist-packages (from pandas>1.5->esda) (2025.2)
Requirement already satisfied: joblib>=1.2.0 in /usr/local/lib/python3.11/dist-packages (from scikit-learn>=1.2->esda) (1.5.1)
Requirement already satisfied: threadpoolctl>=3.1.0 in /usr/local/lib/python3.11/dist-packages (from scikit-learn>=1.2->esda) (3.6.0)
Requirement already satisfied: soupsieve>1.2 in /usr/local/lib/python3.11/dist-packages (from beautifulsoup4>=4.10->libpysal>=4.12->esda) (2.7)
Requirement already satisfied: typing-extensions>=4.0.0 in /usr/local/lib/python3.11/dist-packages (from beautifulsoup4>=4.10->libpysal>=4.12->esda) (4.14.0)
Requirement already satisfied: certifi in /usr/local/lib/python3.11/dist-packages (from pyogrio>=0.7.2->geopandas>=0.12->esda) (2025.6.15)
Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.11/dist-packages (from python-dateutil>=2.8.2->pandas>1.5->esda) (1.17.0)
Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.11/dist-packages (from requests>=2.27->libpysal>=4.12->esda) (3.4.2)
Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.11/dist-packages (from requests>=2.27->libpysal>=4.12->esda) (3.10)
Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.11/dist-packages (from requests>=2.27->libpysal>=4.12->esda) (2.4.0)
In [184]:
w_knn8 = KNN.from_dataframe(data, k=8)

IDH

In [185]:
from esda.moran import Moran

moranIDH = Moran(data['IDH_2022'], w_knn8)
moranIDH.I,moranIDH.p_sim
# se muestra que casi no hay correlación y que este resultado no es coincidencia. Esto se debe a que
# estamos trabajando con muy poca data
Out[185]:
(np.float64(0.0552915250637212), np.float64(0.04))
In [186]:
!pip install splot
Requirement already satisfied: splot in /usr/local/lib/python3.11/dist-packages (1.1.7)
Requirement already satisfied: esda in /usr/local/lib/python3.11/dist-packages (from splot) (2.7.0)
Requirement already satisfied: geopandas>=0.9.0 in /usr/local/lib/python3.11/dist-packages (from splot) (1.0.1)
Requirement already satisfied: giddy in /usr/local/lib/python3.11/dist-packages (from splot) (2.3.6)
Requirement already satisfied: libpysal in /usr/local/lib/python3.11/dist-packages (from splot) (4.13.0)
Requirement already satisfied: mapclassify in /usr/local/lib/python3.11/dist-packages (from splot) (2.9.0)
Requirement already satisfied: matplotlib>=3.3.3 in /usr/local/lib/python3.11/dist-packages (from splot) (3.10.0)
Requirement already satisfied: numpy in /usr/local/lib/python3.11/dist-packages (from splot) (2.0.2)
Requirement already satisfied: packaging in /usr/local/lib/python3.11/dist-packages (from splot) (24.2)
Requirement already satisfied: seaborn>=0.11.0 in /usr/local/lib/python3.11/dist-packages (from splot) (0.13.2)
Requirement already satisfied: spreg in /usr/local/lib/python3.11/dist-packages (from splot) (1.8.3)
Requirement already satisfied: pyogrio>=0.7.2 in /usr/local/lib/python3.11/dist-packages (from geopandas>=0.9.0->splot) (0.11.0)
Requirement already satisfied: pandas>=1.4.0 in /usr/local/lib/python3.11/dist-packages (from geopandas>=0.9.0->splot) (2.2.2)
Requirement already satisfied: pyproj>=3.3.0 in /usr/local/lib/python3.11/dist-packages (from geopandas>=0.9.0->splot) (3.7.1)
Requirement already satisfied: shapely>=2.0.0 in /usr/local/lib/python3.11/dist-packages (from geopandas>=0.9.0->splot) (2.1.1)
Requirement already satisfied: contourpy>=1.0.1 in /usr/local/lib/python3.11/dist-packages (from matplotlib>=3.3.3->splot) (1.3.2)
Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.11/dist-packages (from matplotlib>=3.3.3->splot) (0.12.1)
Requirement already satisfied: fonttools>=4.22.0 in /usr/local/lib/python3.11/dist-packages (from matplotlib>=3.3.3->splot) (4.58.4)
Requirement already satisfied: kiwisolver>=1.3.1 in /usr/local/lib/python3.11/dist-packages (from matplotlib>=3.3.3->splot) (1.4.8)
Requirement already satisfied: pillow>=8 in /usr/local/lib/python3.11/dist-packages (from matplotlib>=3.3.3->splot) (11.2.1)
Requirement already satisfied: pyparsing>=2.3.1 in /usr/local/lib/python3.11/dist-packages (from matplotlib>=3.3.3->splot) (3.2.3)
Requirement already satisfied: python-dateutil>=2.7 in /usr/local/lib/python3.11/dist-packages (from matplotlib>=3.3.3->splot) (2.9.0.post0)
Requirement already satisfied: scikit-learn>=1.2 in /usr/local/lib/python3.11/dist-packages (from esda->splot) (1.6.1)
Requirement already satisfied: scipy>=1.9 in /usr/local/lib/python3.11/dist-packages (from esda->splot) (1.15.3)
Requirement already satisfied: beautifulsoup4>=4.10 in /usr/local/lib/python3.11/dist-packages (from libpysal->splot) (4.13.4)
Requirement already satisfied: platformdirs>=2.0.2 in /usr/local/lib/python3.11/dist-packages (from libpysal->splot) (4.3.8)
Requirement already satisfied: requests>=2.27 in /usr/local/lib/python3.11/dist-packages (from libpysal->splot) (2.32.3)
Requirement already satisfied: quantecon>=0.7 in /usr/local/lib/python3.11/dist-packages (from giddy->splot) (0.8.1)
Requirement already satisfied: networkx>=3.2 in /usr/local/lib/python3.11/dist-packages (from mapclassify->splot) (3.5)
Requirement already satisfied: soupsieve>1.2 in /usr/local/lib/python3.11/dist-packages (from beautifulsoup4>=4.10->libpysal->splot) (2.7)
Requirement already satisfied: typing-extensions>=4.0.0 in /usr/local/lib/python3.11/dist-packages (from beautifulsoup4>=4.10->libpysal->splot) (4.14.0)
Requirement already satisfied: pytz>=2020.1 in /usr/local/lib/python3.11/dist-packages (from pandas>=1.4.0->geopandas>=0.9.0->splot) (2025.2)
Requirement already satisfied: tzdata>=2022.7 in /usr/local/lib/python3.11/dist-packages (from pandas>=1.4.0->geopandas>=0.9.0->splot) (2025.2)
Requirement already satisfied: certifi in /usr/local/lib/python3.11/dist-packages (from pyogrio>=0.7.2->geopandas>=0.9.0->splot) (2025.6.15)
Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.11/dist-packages (from python-dateutil>=2.7->matplotlib>=3.3.3->splot) (1.17.0)
Requirement already satisfied: numba>=0.49.0 in /usr/local/lib/python3.11/dist-packages (from quantecon>=0.7->giddy->splot) (0.60.0)
Requirement already satisfied: sympy in /usr/local/lib/python3.11/dist-packages (from quantecon>=0.7->giddy->splot) (1.13.1)
Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.11/dist-packages (from requests>=2.27->libpysal->splot) (3.4.2)
Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.11/dist-packages (from requests>=2.27->libpysal->splot) (3.10)
Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.11/dist-packages (from requests>=2.27->libpysal->splot) (2.4.0)
Requirement already satisfied: joblib>=1.2.0 in /usr/local/lib/python3.11/dist-packages (from scikit-learn>=1.2->esda->splot) (1.5.1)
Requirement already satisfied: threadpoolctl>=3.1.0 in /usr/local/lib/python3.11/dist-packages (from scikit-learn>=1.2->esda->splot) (3.6.0)
Requirement already satisfied: llvmlite<0.44,>=0.43.0dev0 in /usr/local/lib/python3.11/dist-packages (from numba>=0.49.0->quantecon>=0.7->giddy->splot) (0.43.0)
Requirement already satisfied: mpmath<1.4,>=1.1.0 in /usr/local/lib/python3.11/dist-packages (from sympy->quantecon>=0.7->giddy->splot) (1.3.0)
In [187]:
from splot.esda import moran_scatterplot

fig, ax = moran_scatterplot(moranIDH, aspect_equal=True)
ax.set_xlabel('IDH_std')
ax.set_ylabel('SpatialLag_IDH_std');
No description has been provided for this image

PBI

In [188]:
moranPBI = Moran(data['GDPperCapita_2023'], w_knn8)
moranPBI.I,moranPBI.p_sim
Out[188]:
(np.float64(0.17491730909895079), np.float64(0.006))
In [189]:
fig, ax = moran_scatterplot(moranPBI, aspect_equal=True)
ax.set_xlabel('PBI_std')
ax.set_ylabel('SpatialLag_PBI_std');
No description has been provided for this image

HomRate

In [190]:
moranHomRate = Moran(data['HomicideRate_2023'], w_knn8)
moranHomRate.I,moranHomRate.p_sim
Out[190]:
(np.float64(0.13839147448544573), np.float64(0.002))
In [191]:
fig, ax = moran_scatterplot(moranHomRate, aspect_equal=True)
ax.set_xlabel('Homicide_Rate_std')
ax.set_ylabel('SpatialLag_Homicide_Rate_std');
No description has been provided for this image

Ejercicio 8¶

  1. Compute the Local Moran for the variables in your data that have significant spatial correlation.
  2. Create a new column for each of those variables, with a label ('0 no_sig', '1 hotSpot', '2 coldOutlier', '3 coldSpot', '4 hotOutlier').
  3. Prepare a map for each of the variables analyzed, showing the spots and outliers.

IDH

In [192]:
from esda.moran import Moran_Local
lisaIDH = Moran_Local(y=data['IDH_2022'], w=w_knn8,seed=2022)
In [193]:
fig, ax = moran_scatterplot(lisaIDH,p=0.05)
ax.set_xlabel('IDH_std')
ax.set_ylabel('SpatialLag_IDH_std');
No description has been provided for this image
In [194]:
data['IDH_quadrant']=[l if p <0.05 else 0 for l,p in zip(lisaIDH.q,lisaIDH.p_sim)]
data['IDH_quadrant'].value_counts()
Out[194]:
count
IDH_quadrant
1 5
3 3
4 3
2 2

In [195]:
labels = ['1 hotSpot', '2 coldOutlier', '3 coldSpot', '4 hotOutlier']
data['IDH_quadrant_names']=[labels[i-1] for i in data['IDH_quadrant']]
data['IDH_quadrant_names'].value_counts()
Out[195]:
count
IDH_quadrant_names
1 hotSpot 5
3 coldSpot 3
4 hotOutlier 3
2 coldOutlier 2

In [196]:
import matplotlib.pyplot as plt
from matplotlib import colors
myColMap = colors.ListedColormap(['pink', 'cyan', 'azure','red'])

f, ax = plt.subplots(1, figsize=(6,6))
# Plot unique values choropleth including
# a legend and with no boundary lines

plt.title('Spots and Outliers for IDH')

data.plot(column='IDH_quadrant_names',
                categorical=True,
                cmap=myColMap,
                linewidth=0.1,
                edgecolor='k',
                legend=True,
                legend_kwds={'loc': 'center left',
                             'bbox_to_anchor': (0.7, 0.6)},
                ax=ax)
# Remove axis
ax.set_axis_off()
# Display the map
plt.show()
No description has been provided for this image

PBI

In [197]:
from esda.moran import Moran_Local
lisaPBI = Moran_Local(y=data['GDPperCapita_2023'], w=w_knn8,seed=2022)
In [198]:
data['PBI_quadrant']=[l if p <0.05 else 0 for l,p in zip(lisaPBI.q,lisaPBI.p_sim)]
data['PBI_quadrant'].value_counts()
Out[198]:
count
PBI_quadrant
1 5
0 5
2 2
3 1

In [199]:
labels = ["0 no_sig",'1 hotSpot', '2 coldOutlier', '3 coldSpot', '4 hotOutlier']
data['PBI_quadrant_names']=[labels[i] for i in data['PBI_quadrant']]
data['PBI_quadrant_names'].value_counts()
Out[199]:
count
PBI_quadrant_names
1 hotSpot 5
0 no_sig 5
2 coldOutlier 2
3 coldSpot 1

In [200]:
import matplotlib.pyplot as plt
from matplotlib import colors
myColMap = colors.ListedColormap(['white','pink', 'cyan', 'azure','red'])

f, ax = plt.subplots(1, figsize=(6,6))

plt.title('Spots and Outliers for PBI')

data.plot(column='PBI_quadrant_names',
                categorical=True,
                cmap=myColMap,
                linewidth=0.1,
                edgecolor='k',
                legend=True,
                legend_kwds={'loc': 'center left',
                             'bbox_to_anchor': (0.7, 0.6)},
                ax=ax)
# Remove axis
ax.set_axis_off()
# Display the map
plt.show()
No description has been provided for this image

Homicide Rate

In [201]:
from esda.moran import Moran_Local
lisaHomRate = Moran_Local(y=data['HomicideRate_2023'], w=w_knn8,seed=2022)
In [202]:
data['HomRate_quadrant']=[l if p <0.05 else 0 for l,p in zip(lisaHomRate.q,lisaHomRate.p_sim)]
data['HomRate_quadrant'].value_counts()
Out[202]:
count
HomRate_quadrant
1 5
0 5
2 2
3 1

In [203]:
labels = ["0 no_sig",'1 hotSpot', '2 coldOutlier', '3 coldSpot', '4 hotOutlier']
data['HomRate_quadrant_names']=[labels[i] for i in data['HomRate_quadrant']]
data['HomRate_quadrant_names'].value_counts()
Out[203]:
count
HomRate_quadrant_names
1 hotSpot 5
0 no_sig 5
2 coldOutlier 2
3 coldSpot 1

In [204]:
myColMap = colors.ListedColormap([ 'white', 'pink', 'cyan', 'azure','red'])

f, ax = plt.subplots(1, figsize=(6,6))

plt.title('Spots and Outliers for Homicide Rate')

data.plot(column='HomRate_quadrant_names',
                categorical=True,
                cmap=myColMap,
                linewidth=0.1,
                edgecolor='k',
                legend=True,
                legend_kwds={'loc': 'center left',
                             'bbox_to_anchor': (0.7, 0.6)},
                ax=ax)
# Remove axis
ax.set_axis_off()
# Display the map
plt.show()
No description has been provided for this image

Ejercicio 9¶

Use your three variables to carry out the cluster/regional analysis.

In [205]:
data.head()
Out[205]:
COUNTRY PROVINCIA geometry IDH_2022 Poblacion GDPperCapita_2023 HomicideRate_2023 IDH_quadrant IDH_quadrant_names PBI_quadrant PBI_quadrant_names HomRate_quadrant HomRate_quadrant_names
0 CANADA ALBERTA MULTIPOLYGON (((-1191696.513 1131094.24, -1193... 0.947 4684514 96576 2.45 1 1 hotSpot 1 1 hotSpot 2 2 coldOutlier
1 CANADA BRITISH COLUMBIA MULTIPOLYGON (((-1994216.432 1323427.567, -199... 0.946 5531553 74099 2.23 1 1 hotSpot 2 2 coldOutlier 2 2 coldOutlier
2 CANADA MANITOBA MULTIPOLYGON (((-225729.524 989985.252, -22714... 0.907 1454743 63153 5.09 2 2 coldOutlier 2 2 coldOutlier 1 1 hotSpot
3 CANADA NEW BRUNSWICK MULTIPOLYGON (((2280813.977 989844.48, 2280788... 0.904 832190 56520 1.08 3 3 coldSpot 0 0 no_sig 0 0 no_sig
4 CANADA NEWFOUNDLAND AND LABRADOR MULTIPOLYGON (((3062487.374 1723165.753, 30624... 0.901 538907 72293 1.49 3 3 coldSpot 0 0 no_sig 0 0 no_sig
In [206]:
selected_variables = ['GDPperCapita_2023','HomicideRate_2023','IDH_2022']
In [207]:
data[selected_variables].corr()
Out[207]:
GDPperCapita_2023 HomicideRate_2023 IDH_2022
GDPperCapita_2023 1.000000 0.761963 0.396979
HomicideRate_2023 0.761963 1.000000 0.104080
IDH_2022 0.396979 0.104080 1.000000
In [208]:
import seaborn as sea
In [209]:
sea.pairplot(data[selected_variables], kind="reg", diag_kind="kde")
Out[209]:
<seaborn.axisgrid.PairGrid at 0x792902601250>
No description has been provided for this image
In [210]:
# hay que invertir Homicide Rate porque se espera que a mayor IDH o GDP, el Homicide Rate sea menor
from sklearn.preprocessing import StandardScaler


scaler = StandardScaler()
normalized_data = scaler.fit_transform(data[selected_variables])
sea.displot(pd.melt(pd.DataFrame(normalized_data,columns=selected_variables)),
            x="value", hue="variable",kind="kde",
            log_scale=(False,False))
Out[210]:
<seaborn.axisgrid.FacetGrid at 0x7928f0716090>
No description has been provided for this image
In [211]:
# new names
selected_variables_new_std=[s+'_std' for s in selected_variables]

# add colunms
data[selected_variables_new_std]=normalized_data
In [213]:
data.head()
Out[213]:
COUNTRY PROVINCIA geometry IDH_2022 Poblacion GDPperCapita_2023 HomicideRate_2023 IDH_quadrant IDH_quadrant_names PBI_quadrant PBI_quadrant_names HomRate_quadrant HomRate_quadrant_names GDPperCapita_2023_std HomicideRate_2023_std IDH_2022_std
0 CANADA ALBERTA MULTIPOLYGON (((-1191696.513 1131094.24, -1193... 0.947 4684514 96576 2.45 1 1 hotSpot 1 1 hotSpot 2 2 coldOutlier 0.756766 -0.370997 1.509748
1 CANADA BRITISH COLUMBIA MULTIPOLYGON (((-1994216.432 1323427.567, -199... 0.946 5531553 74099 2.23 1 1 hotSpot 2 2 coldOutlier 2 2 coldOutlier -0.271396 -0.432543 1.442762
2 CANADA MANITOBA MULTIPOLYGON (((-225729.524 989985.252, -22714... 0.907 1454743 63153 5.09 2 2 coldOutlier 2 2 coldOutlier 1 1 hotSpot -0.772097 0.367554 -1.169668
3 CANADA NEW BRUNSWICK MULTIPOLYGON (((2280813.977 989844.48, 2280788... 0.904 832190 56520 1.08 3 3 coldSpot 0 0 no_sig 0 0 no_sig -1.075509 -0.754260 -1.370624
4 CANADA NEWFOUNDLAND AND LABRADOR MULTIPOLYGON (((3062487.374 1723165.753, 30624... 0.901 538907 72293 1.49 3 3 coldSpot 0 0 no_sig 0 0 no_sig -0.354007 -0.639561 -1.571580
5 CANADA NORTHWEST TERRITORIES MULTIPOLYGON (((-932976.987 3668489.676, -9330... 0.929 44681 122602 13.34 1 1 hotSpot 1 1 hotSpot 1 1 hotSpot 1.947269 2.675526 0.304011
6 CANADA NOVA SCOTIA MULTIPOLYGON (((2419990.709 926493.096, 242000... 0.909 1056486 56389 1.32 3 3 coldSpot 0 0 no_sig 0 0 no_sig -1.081502 -0.687119 -1.035697
7 CANADA NUNAVUT MULTIPOLYGON (((1581589.008 2742840.281, 15815... 0.929 40700 118550 4.92 1 1 hotSpot 1 1 hotSpot 1 1 hotSpot 1.761919 0.319996 0.304011
8 CANADA ONTARIO MULTIPOLYGON (((1409005.46 492629.458, 1408574... 0.942 15623207 71659 1.68 4 4 hotOutlier 3 3 coldSpot 3 3 coldSpot -0.383008 -0.586408 1.174821
9 CANADA PRINCE EDWARD ISLAND MULTIPOLYGON (((2505095.555 1289997.862, 25051... 0.929 173713 57129 0.58 4 4 hotOutlier 0 0 no_sig 0 0 no_sig -1.047652 -0.894137 0.304011
10 CANADA QUEBEC MULTIPOLYGON (((1678607.031 812858.207, 167861... 0.926 8848020 65490 1.14 4 4 hotOutlier 0 0 no_sig 0 0 no_sig -0.665196 -0.737475 0.103054
11 CANADA SASKATCHEWAN MULTIPOLYGON (((-479648.471 1008211.632, -4796... 0.920 1209307 90715 4.88 2 2 coldOutlier 1 1 hotSpot 1 1 hotSpot 0.488667 0.308806 -0.298858
12 CANADA YUKON MULTIPOLYGON (((-1485495.114 2531187.928, -148... 0.929 45463 95242 8.89 1 1 hotSpot 1 1 hotSpot 1 1 hotSpot 0.695745 1.430620 0.304011
In [214]:
data['HomicideRate_Inverso_2023_std']=-1*data.HomicideRate_2023_std
In [216]:
# as a result:
selected_variables_new_std = ['HomicideRate_Inverso_2023_std',
                     'GDPperCapita_2023_std',
                     'IDH_2022_std']
sea.pairplot(
    data[selected_variables_new_std], kind="reg", diag_kind="kde"
)
Out[216]:
<seaborn.axisgrid.PairGrid at 0x7928d351e450>
No description has been provided for this image

Conventinoal clustering

In [217]:
from scipy.cluster import hierarchy as hc


Z = hc.linkage(data[selected_variables_new_std], 'ward')
# calculate full dendrogram
plt.figure(figsize=(25, 10))
plt.title('Hierarchical Clustering Dendrogram')
plt.xlabel('cases')
plt.ylabel('distance')
hc.dendrogram(
    Z,
    leaf_rotation=90.,  # rotates the x axis labels
    leaf_font_size=1,  # font size for the x axis labels
)
plt.show()
No description has been provided for this image
In [219]:
from sklearn.cluster import AgglomerativeClustering as agnes

import numpy as np
np.random.seed(12345)# Set seed for reproducibility

# Initialize the algorithm, requesting 3 clusters
model = agnes(linkage="ward", n_clusters=3).fit(data[selected_variables_new_std])

# Assign labels to main data table
data["hc_ag3"] = model.labels_
In [220]:
data["hc_ag3"].value_counts()
Out[220]:
count
hc_ag3
1 5
2 4
0 4

In [221]:
# Set up figure and ax
f, ax = plt.subplots(1, figsize=(9, 9))
# Plot unique values choropleth including
# a legend and with no boundary lines
data.plot(
    column="hc_ag3", categorical=True, legend=True, linewidth=0, ax=ax
)
# Remove axis
ax.set_axis_off()
# Display the map
plt.show()
No description has been provided for this image

Regionalized clustering

In [224]:
w_queen = Queen.from_dataframe(data,use_index=False)
In [225]:
model_queen = agnes(linkage="ward", n_clusters=3, connectivity=w_queen.sparse).fit(data[selected_variables_new_std])
data["hc_ag3_wQueen"] = model_queen.labels_
In [226]:
# Set up figure and ax
f, ax = plt.subplots(1, figsize=(9, 9))
# Plot unique values choropleth including a legend and with no boundary lines
data.plot(
    column="hc_ag3_wQueen",
    categorical=True,
    legend=True,
    linewidth=0,
    ax=ax,
)
# Remove axis
ax.set_axis_off()
# Display the map
plt.show()
No description has been provided for this image
In [228]:
# para ver qué clustering es el más adecuado, podemos ver la compacidad de cada método
from esda import shape as shapestats
results={}
for cluster_type in ("hc_ag3_wQueen", "hc_ag3"):
    # compute the region polygons using a dissolve
    regions = data[[cluster_type, "geometry"]].to_crs("ESRI:102001").dissolve(by=cluster_type)
    # compute the actual convex hull quotient for these regions
    chullr = shapestats.convex_hull_ratio(regions)
    # cast to a dataframe
    result = {cluster_type:chullr}
    results.update(result)
# stack the series together along columns
pd.DataFrame(results)
Out[228]:
hc_ag3_wQueen hc_ag3
0 0.494340 0.494340
1 0.601777 0.462117
2 0.828507 0.223788
In [232]:
# segun este criterio, se puede decir que spatial clustering fue más efectivo para Canada
In [231]:
from sklearn import metrics

fit_scores = []
for cluster_type in ("hc_ag3_wQueen", "hc_ag3"):
    # compute the CH score
    ch_score = metrics.calinski_harabasz_score(
        # using scaled variables
        data[selected_variables_new_std],
        # using these labels
        data[cluster_type],
    )
    sil_score = metrics.silhouette_score(
        # using scaled variables
        data[selected_variables_new_std],
        # using these labels
        data[cluster_type],
    )
    # and append the cluster type with the CH score
    fit_scores.append((cluster_type, ch_score,sil_score))


# re-arrange the scores into a dataframe for display
pd.DataFrame(
    fit_scores, columns=["cluster type", "CH score", "SIL score"]
).set_index("cluster type")
Out[231]:
CH score SIL score
cluster type
hc_ag3_wQueen 8.581915 0.293870
hc_ag3 13.048216 0.428276
In [233]:
# segun este criterio, el clustering convencional es el más adecuado

Ejercicio 10¶

Use your three variables to carry out regression analysis (conventional and spatial).

In [230]:
!pip install pysal
Collecting pysal
  Downloading pysal-25.1-py3-none-any.whl.metadata (15 kB)
Requirement already satisfied: beautifulsoup4>=4.10 in /usr/local/lib/python3.11/dist-packages (from pysal) (4.13.4)
Requirement already satisfied: geopandas>=0.10.0 in /usr/local/lib/python3.11/dist-packages (from pysal) (1.0.1)
Requirement already satisfied: numpy>=1.22 in /usr/local/lib/python3.11/dist-packages (from pysal) (2.0.2)
Requirement already satisfied: packaging>=22 in /usr/local/lib/python3.11/dist-packages (from pysal) (24.2)
Requirement already satisfied: pandas>=1.4 in /usr/local/lib/python3.11/dist-packages (from pysal) (2.2.2)
Requirement already satisfied: platformdirs>=2.0.2 in /usr/local/lib/python3.11/dist-packages (from pysal) (4.3.8)
Requirement already satisfied: requests>=2.27 in /usr/local/lib/python3.11/dist-packages (from pysal) (2.32.3)
Requirement already satisfied: scipy>=1.8 in /usr/local/lib/python3.11/dist-packages (from pysal) (1.15.3)
Requirement already satisfied: shapely>=2.0.1 in /usr/local/lib/python3.11/dist-packages (from pysal) (2.1.1)
Requirement already satisfied: scikit-learn>=1.1 in /usr/local/lib/python3.11/dist-packages (from pysal) (1.6.1)
Requirement already satisfied: libpysal>=4.12.1 in /usr/local/lib/python3.11/dist-packages (from pysal) (4.13.0)
Collecting access>=1.1.9 (from pysal)
  Downloading access-1.1.9-py3-none-any.whl.metadata (2.4 kB)
Requirement already satisfied: esda>=2.6.0 in /usr/local/lib/python3.11/dist-packages (from pysal) (2.7.0)
Requirement already satisfied: giddy>=2.3.6 in /usr/local/lib/python3.11/dist-packages (from pysal) (2.3.6)
Collecting inequality>=1.1.1 (from pysal)
  Downloading inequality-1.1.1-py3-none-any.whl.metadata (3.9 kB)
Collecting pointpats>=2.5.1 (from pysal)
  Downloading pointpats-2.5.1-py3-none-any.whl.metadata (4.7 kB)
Collecting segregation>=2.5.1 (from pysal)
  Downloading segregation-2.5.2-py3-none-any.whl.metadata (2.2 kB)
Collecting spaghetti>=1.7.6 (from pysal)
  Downloading spaghetti-1.7.6-py3-none-any.whl.metadata (12 kB)
Collecting mgwr>=2.2.1 (from pysal)
  Downloading mgwr-2.2.1-py3-none-any.whl.metadata (1.5 kB)
Collecting momepy>=0.9.1 (from pysal)
  Downloading momepy-0.10.0-py3-none-any.whl.metadata (1.5 kB)
Collecting spglm>=1.1.0 (from pysal)
  Downloading spglm-1.1.0-py3-none-any.whl.metadata (3.9 kB)
Collecting spint>=1.0.7 (from pysal)
  Downloading spint-1.0.7.tar.gz (28 kB)
  Preparing metadata (setup.py) ... done
Requirement already satisfied: spreg>=1.8.1 in /usr/local/lib/python3.11/dist-packages (from pysal) (1.8.3)
Collecting tobler>=0.12.1 (from pysal)
  Downloading tobler-0.12.1-py3-none-any.whl.metadata (1.9 kB)
Requirement already satisfied: mapclassify>=2.8.1 in /usr/local/lib/python3.11/dist-packages (from pysal) (2.9.0)
Requirement already satisfied: splot>=1.1.7 in /usr/local/lib/python3.11/dist-packages (from pysal) (1.1.7)
Collecting spopt>=0.6.1 (from pysal)
  Downloading spopt-0.6.1-py3-none-any.whl.metadata (10 kB)
Requirement already satisfied: soupsieve>1.2 in /usr/local/lib/python3.11/dist-packages (from beautifulsoup4>=4.10->pysal) (2.7)
Requirement already satisfied: typing-extensions>=4.0.0 in /usr/local/lib/python3.11/dist-packages (from beautifulsoup4>=4.10->pysal) (4.14.0)
Requirement already satisfied: pyogrio>=0.7.2 in /usr/local/lib/python3.11/dist-packages (from geopandas>=0.10.0->pysal) (0.11.0)
Requirement already satisfied: pyproj>=3.3.0 in /usr/local/lib/python3.11/dist-packages (from geopandas>=0.10.0->pysal) (3.7.1)
Requirement already satisfied: quantecon>=0.7 in /usr/local/lib/python3.11/dist-packages (from giddy>=2.3.6->pysal) (0.8.1)
Requirement already satisfied: matplotlib>=3.6 in /usr/local/lib/python3.11/dist-packages (from inequality>=1.1.1->pysal) (3.10.0)
Requirement already satisfied: networkx>=3.2 in /usr/local/lib/python3.11/dist-packages (from mapclassify>=2.8.1->pysal) (3.5)
Requirement already satisfied: tqdm>=4.65 in /usr/local/lib/python3.11/dist-packages (from momepy>=0.9.1->pysal) (4.67.1)
Requirement already satisfied: python-dateutil>=2.8.2 in /usr/local/lib/python3.11/dist-packages (from pandas>=1.4->pysal) (2.9.0.post0)
Requirement already satisfied: pytz>=2020.1 in /usr/local/lib/python3.11/dist-packages (from pandas>=1.4->pysal) (2025.2)
Requirement already satisfied: tzdata>=2022.7 in /usr/local/lib/python3.11/dist-packages (from pandas>=1.4->pysal) (2025.2)
Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.11/dist-packages (from requests>=2.27->pysal) (3.4.2)
Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.11/dist-packages (from requests>=2.27->pysal) (3.10)
Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.11/dist-packages (from requests>=2.27->pysal) (2.4.0)
Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.11/dist-packages (from requests>=2.27->pysal) (2025.6.15)
Requirement already satisfied: joblib>=1.2.0 in /usr/local/lib/python3.11/dist-packages (from scikit-learn>=1.1->pysal) (1.5.1)
Requirement already satisfied: threadpoolctl>=3.1.0 in /usr/local/lib/python3.11/dist-packages (from scikit-learn>=1.1->pysal) (3.6.0)
Collecting deprecation (from segregation>=2.5.1->pysal)
  Downloading deprecation-2.1.0-py2.py3-none-any.whl.metadata (4.6 kB)
Requirement already satisfied: seaborn in /usr/local/lib/python3.11/dist-packages (from segregation>=2.5.1->pysal) (0.13.2)
Requirement already satisfied: numba in /usr/local/lib/python3.11/dist-packages (from segregation>=2.5.1->pysal) (0.60.0)
Collecting rtree>=1.0 (from spaghetti>=1.7.6->pysal)
  Downloading rtree-1.4.0-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.metadata (2.1 kB)
Collecting pulp>=2.7 (from spopt>=0.6.1->pysal)
  Downloading pulp-3.2.1-py3-none-any.whl.metadata (6.9 kB)
Collecting rasterio (from tobler>=0.12.1->pysal)
  Downloading rasterio-1.4.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (9.1 kB)
Requirement already satisfied: statsmodels in /usr/local/lib/python3.11/dist-packages (from tobler>=0.12.1->pysal) (0.14.4)
Collecting rasterstats (from tobler>=0.12.1->pysal)
  Downloading rasterstats-0.20.0-py3-none-any.whl.metadata (4.2 kB)
Requirement already satisfied: contourpy>=1.0.1 in /usr/local/lib/python3.11/dist-packages (from matplotlib>=3.6->inequality>=1.1.1->pysal) (1.3.2)
Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.11/dist-packages (from matplotlib>=3.6->inequality>=1.1.1->pysal) (0.12.1)
Requirement already satisfied: fonttools>=4.22.0 in /usr/local/lib/python3.11/dist-packages (from matplotlib>=3.6->inequality>=1.1.1->pysal) (4.58.4)
Requirement already satisfied: kiwisolver>=1.3.1 in /usr/local/lib/python3.11/dist-packages (from matplotlib>=3.6->inequality>=1.1.1->pysal) (1.4.8)
Requirement already satisfied: pillow>=8 in /usr/local/lib/python3.11/dist-packages (from matplotlib>=3.6->inequality>=1.1.1->pysal) (11.2.1)
Requirement already satisfied: pyparsing>=2.3.1 in /usr/local/lib/python3.11/dist-packages (from matplotlib>=3.6->inequality>=1.1.1->pysal) (3.2.3)
Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.11/dist-packages (from python-dateutil>=2.8.2->pandas>=1.4->pysal) (1.17.0)
Requirement already satisfied: sympy in /usr/local/lib/python3.11/dist-packages (from quantecon>=0.7->giddy>=2.3.6->pysal) (1.13.1)
Requirement already satisfied: llvmlite<0.44,>=0.43.0dev0 in /usr/local/lib/python3.11/dist-packages (from numba->segregation>=2.5.1->pysal) (0.43.0)
Collecting affine (from rasterio->tobler>=0.12.1->pysal)
  Downloading affine-2.4.0-py3-none-any.whl.metadata (4.0 kB)
Requirement already satisfied: attrs in /usr/local/lib/python3.11/dist-packages (from rasterio->tobler>=0.12.1->pysal) (25.3.0)
Requirement already satisfied: click>=4.0 in /usr/local/lib/python3.11/dist-packages (from rasterio->tobler>=0.12.1->pysal) (8.2.1)
Collecting cligj>=0.5 (from rasterio->tobler>=0.12.1->pysal)
  Downloading cligj-0.7.2-py3-none-any.whl.metadata (5.0 kB)
Collecting click-plugins (from rasterio->tobler>=0.12.1->pysal)
  Downloading click_plugins-1.1.1.2-py2.py3-none-any.whl.metadata (6.5 kB)
Collecting fiona (from rasterstats->tobler>=0.12.1->pysal)
  Downloading fiona-1.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (56 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 56.6/56.6 kB 3.1 MB/s eta 0:00:00
Requirement already satisfied: simplejson in /usr/local/lib/python3.11/dist-packages (from rasterstats->tobler>=0.12.1->pysal) (3.20.1)
Requirement already satisfied: patsy>=0.5.6 in /usr/local/lib/python3.11/dist-packages (from statsmodels->tobler>=0.12.1->pysal) (1.0.1)
Requirement already satisfied: mpmath<1.4,>=1.1.0 in /usr/local/lib/python3.11/dist-packages (from sympy->quantecon>=0.7->giddy>=2.3.6->pysal) (1.3.0)
Downloading pysal-25.1-py3-none-any.whl (17 kB)
Downloading access-1.1.9-py3-none-any.whl (21 kB)
Downloading inequality-1.1.1-py3-none-any.whl (29 kB)
Downloading mgwr-2.2.1-py3-none-any.whl (47 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 47.9/47.9 kB 2.4 MB/s eta 0:00:00
Downloading momepy-0.10.0-py3-none-any.whl (1.7 MB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.7/1.7 MB 28.5 MB/s eta 0:00:00
Downloading pointpats-2.5.1-py3-none-any.whl (59 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 59.2/59.2 kB 4.2 MB/s eta 0:00:00
Downloading segregation-2.5.2-py3-none-any.whl (141 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 141.6/141.6 kB 6.7 MB/s eta 0:00:00
Downloading spaghetti-1.7.6-py3-none-any.whl (53 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 53.9/53.9 kB 2.7 MB/s eta 0:00:00
Downloading spglm-1.1.0-py3-none-any.whl (41 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 41.4/41.4 kB 2.1 MB/s eta 0:00:00
Downloading spopt-0.6.1-py3-none-any.whl (243 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 243.1/243.1 kB 7.7 MB/s eta 0:00:00
Downloading tobler-0.12.1-py3-none-any.whl (28 kB)
Downloading pulp-3.2.1-py3-none-any.whl (16.4 MB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 16.4/16.4 MB 35.2 MB/s eta 0:00:00
Downloading rtree-1.4.0-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (541 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 541.1/541.1 kB 28.2 MB/s eta 0:00:00
Downloading deprecation-2.1.0-py2.py3-none-any.whl (11 kB)
Downloading rasterio-1.4.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (22.2 MB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 22.2/22.2 MB 24.1 MB/s eta 0:00:00
Downloading rasterstats-0.20.0-py3-none-any.whl (17 kB)
Downloading cligj-0.7.2-py3-none-any.whl (7.1 kB)
Downloading affine-2.4.0-py3-none-any.whl (15 kB)
Downloading click_plugins-1.1.1.2-py2.py3-none-any.whl (11 kB)
Downloading fiona-1.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (17.3 MB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 17.3/17.3 MB 73.3 MB/s eta 0:00:00
Building wheels for collected packages: spint
  Building wheel for spint (setup.py) ... done
  Created wheel for spint: filename=spint-1.0.7-py3-none-any.whl size=31354 sha256=75cc4de75cbfabdcbedf5bffa73952ff00298407a1f21e3b5b854d0ea94fda01
  Stored in directory: /root/.cache/pip/wheels/32/dc/2e/400caaa67e697355772a82b77b8c2ac7cd61633f595c477fd8
Successfully built spint
Installing collected packages: rtree, pulp, deprecation, cligj, click-plugins, affine, rasterio, fiona, rasterstats, access, tobler, segregation, pointpats, momepy, inequality, spglm, spaghetti, spopt, spint, mgwr, pysal
Successfully installed access-1.1.9 affine-2.4.0 click-plugins-1.1.1.2 cligj-0.7.2 deprecation-2.1.0 fiona-1.10.1 inequality-1.1.1 mgwr-2.2.1 momepy-0.10.0 pointpats-2.5.1 pulp-3.2.1 pysal-25.1 rasterio-1.4.3 rasterstats-0.20.0 rtree-1.4.0 segregation-2.5.2 spaghetti-1.7.6 spglm-1.1.0 spint-1.0.7 spopt-0.6.1 tobler-0.12.1
In [234]:
data.head()
Out[234]:
COUNTRY PROVINCIA geometry IDH_2022 Poblacion GDPperCapita_2023 HomicideRate_2023 IDH_quadrant IDH_quadrant_names PBI_quadrant PBI_quadrant_names HomRate_quadrant HomRate_quadrant_names GDPperCapita_2023_std HomicideRate_2023_std IDH_2022_std HomicideRate_Inverso_2023_std hc_ag3 hc_ag3_wQueen
0 CANADA ALBERTA MULTIPOLYGON (((-1191696.513 1131094.24, -1193... 0.947 4684514 96576 2.45 1 1 hotSpot 1 1 hotSpot 2 2 coldOutlier 0.756766 -0.370997 1.509748 0.370997 1 2
1 CANADA BRITISH COLUMBIA MULTIPOLYGON (((-1994216.432 1323427.567, -199... 0.946 5531553 74099 2.23 1 1 hotSpot 2 2 coldOutlier 2 2 coldOutlier -0.271396 -0.432543 1.442762 0.432543 1 2
2 CANADA MANITOBA MULTIPOLYGON (((-225729.524 989985.252, -22714... 0.907 1454743 63153 5.09 2 2 coldOutlier 2 2 coldOutlier 1 1 hotSpot -0.772097 0.367554 -1.169668 -0.367554 2 1
3 CANADA NEW BRUNSWICK MULTIPOLYGON (((2280813.977 989844.48, 2280788... 0.904 832190 56520 1.08 3 3 coldSpot 0 0 no_sig 0 0 no_sig -1.075509 -0.754260 -1.370624 0.754260 2 1
4 CANADA NEWFOUNDLAND AND LABRADOR MULTIPOLYGON (((3062487.374 1723165.753, 30624... 0.901 538907 72293 1.49 3 3 coldSpot 0 0 no_sig 0 0 no_sig -0.354007 -0.639561 -1.571580 0.639561 2 1
In [235]:
from pysal.model import spreg

dep_var_name=['HomicideRate_2023']
ind_vars_names=['GDPperCapita_2023','IDH_2022']
labels=['Homicide Rate %','GDP per capita', 'Indice desarrollo humano %']

ols_model = spreg.OLS(
    # Dependent variable
    data[dep_var_name].values,
    # Independent variables
    data[ind_vars_names].values,
    # Dependent variable name
    name_y=labels[0],
    # Independent variable name
    name_x=labels[1:],
    name_ds='data')

print(ols_model.summary)
REGRESSION RESULTS
------------------

SUMMARY OF OUTPUT: ORDINARY LEAST SQUARES
-----------------------------------------
Data set            :        data
Weights matrix      :        None
Dependent Variable  :Homicide Rate %                Number of Observations:          13
Mean dependent var  :      3.7762                Number of Variables   :           3
S.D. dependent var  :      3.7205                Degrees of Freedom    :          10
R-squared           :      0.6273
Adjusted R-squared  :      0.5528
Sum squared residual:     61.9058                F-statistic           :      8.4162
Sigma-square        :       6.191                Prob(F-statistic)     :     0.00719
S.E. of regression  :       2.488                Log likelihood        :     -28.591
Sigma-square ML     :       4.762                Akaike info criterion :      63.181
S.E of regression ML:      2.1822                Schwarz criterion     :      64.876

------------------------------------------------------------------------------------
            Variable     Coefficient       Std.Error     t-Statistic     Probability
------------------------------------------------------------------------------------
            CONSTANT        44.71528        45.54150         0.98186         0.34933
      GDP per capita         0.00014         0.00003         4.06715         0.00226
Indice desarrollo humano %       -56.39365        50.36316        -1.11974         0.28900
------------------------------------------------------------------------------------

REGRESSION DIAGNOSTICS
MULTICOLLINEARITY CONDITION NUMBER         162.176

TEST ON NORMALITY OF ERRORS
TEST                             DF        VALUE           PROB
Jarque-Bera                       2          0.224           0.8939

DIAGNOSTICS FOR HETEROSKEDASTICITY
RANDOM COEFFICIENTS
TEST                             DF        VALUE           PROB
Breusch-Pagan test                2          7.276           0.0263
Koenker-Bassett test              2         10.290           0.0058
================================ END OF REPORT =====================================