Introduction
Créer une GeoDataFrame avec une géométrie Polygon à partir d'une simple DataFrame Pandas implique quelques étapes. Ces étapes comprennent la préparation de vos données, l'importation des bibliothèques nécessaires, la création des géométries Polygon, et enfin la construction d'une GeoDataFrame.
Voici un guide étape par étape pour y parvenir:
Créez une DataFrame Pandas avec des coordonnées
Tout d'abord, assurez-vous que votre DataFrame Pandas contient les coordonnées nécessaires pour construire votre polygone. Ces coordonnées doivent être dans un format pouvant être interprété comme des points pour constituer le ou les polygones. En général, il s'agirait de colonnes pour la latitude et la longitude, ou d'une seule colonne avec des tuples/listes contenant les deux valeurs.
import pandas as pd
data = {'city_name':['Paris','London','Moscow', 'Istanbul'],
'longitude_c1':[2.3522-0.1,-0.1276-0.1,37.6173-0.1,28.9784-0.1],
'latitude_c1':[48.8566-0.1,51.5072-0.1,55.7558-0.1,41.0082-0.1],
'longitude_c2':[2.3522-0.1,-0.1276-0.1,37.6173-0.1,28.9784-0.1],
'latitude_c2':[48.8566+0.1,51.5072+0.1,55.7558+0.1,41.0082+0.1],
'longitude_c3':[2.3522+0.1,-0.1276+0.1,37.6173+0.1,28.9784+0.1],
'latitude_c3':[48.8566+0.1,51.5072+0.1,55.7558+0.1,41.0082+0.1],
'longitude_c4':[2.3522+0.1,-0.1276+0.1,37.6173+0.1,28.9784+0.1],
'latitude_c4':[48.8566-0.1,51.5072-0.1,55.7558-0.1,41.0082-0.1]
}
df = pd.DataFrame(data)
print(df)
Cela nous donnera la sortie suivante:
city_name longitude_c1 latitude_c1 longitude_c2 latitude_c2 \
0 Paris 2.2522 48.7566 2.2522 48.9566
1 London -0.2276 51.4072 -0.2276 51.6072
2 Moscow 37.5173 55.6558 37.5173 55.8558
3 Istanbul 28.8784 40.9082 28.8784 41.1082
longitude_c3 latitude_c3 longitude_c4 latitude_c4
0 2.4522 48.9566 2.4522 48.7566
1 -0.0276 51.6072 -0.0276 51.4072
2 37.7173 55.8558 37.7173 55.6558
3 29.0784 41.1082 29.0784 40.9082
Construction de nos polygone(s)
Maintenant, avec cette DataFrame en place, nous pouvons commencer à construire nos polygones en utilisant les coordonnées fournies. Nous utiliserons la bibliothèque shapely pour cette tâche, qui offre diverses opérations géométriques sur ces coordonnées.
Il existe différentes approches pour créer nos polygones, en fonction de la taille de la dataframe. Bien qu'il soit courant de créer une fonction, cela peut devenir lent à mesure que la taille d'une dataframe augmente. Dans de tels cas, l'utilisation de la fonction map() est recommandée.
Approche 1 : Création d'une fonction Python
Pour commencer, nous devons ajouter une nouvelle colonne à notre dataframe qui contiendra les points nécessaires pour construire nos polygones. Cela peut être réalisé en utilisant la fonction apply.
Voici un exemple de comment accomplir cela en utilisant le module shapely.geometry:
from shapely.geometry import Polygon
def create_polygon(x):
p1 = [x['longitude_c1'],x['latitude_c1']]
p2 = [x['longitude_c2'],x['latitude_c2']]
p3 = [x['longitude_c3'],x['latitude_c3']]
p4 = [x['longitude_c4'],x['latitude_c4']]
pixel_polygon = Polygon([p1,p2,p3,p4])
return pixel_polygon
Cela prendra chaque ligne de notre dataframe et utilisera les colonnes de longitude et de latitude pour créer une liste de tuples, qui peuvent être interprétés comme des points.
Ce code itère à travers chaque ligne de notre tableau de données et utilise les colonnes de longitude et latitude pour générer une liste de points.
En invoquant la fonction,
df.apply(create_polygon, axis=1)
Un objet de type pandas.core.series.Series est renvoyé:
0 POLYGON ((2.2522 48.7566, 2.2522 48.9566, 2.45...
1 POLYGON ((-0.2276 51.4072, -0.2276 51.6072, -0...
2 POLYGON ((37.5173 55.6558, 37.5173 55.8558, 37...
3 POLYGON ((28.8784 40.9082, 28.8784 41.1082, 29...
dtype: object
Maintenant, nous avons l'opportunité d'ajouter une nouvelle colonne à notre DataFrame, que nous pouvons nommer "géométrie":
df['geometry'] = df.apply(create_polygon, axis=1)
Nous pouvons également visualiser nos polygones en utilisant la bibliothèque matplotlib, qui propose diverses fonctions de tracé.
import matplotlib.pyplot as plt
plt.figure() # creates a new figure to plot on
for polygon in df['geometry']:
plt.plot(*polygon.exterior.xy) # plots the exterior coordinates of each Polygon object as a line
plt.title('How to create a GeoDataFrame with Polygon geometry \n from a Pandas DataFrame with coordinates ?')
plt.savefig('geopandas_polygons_01.png', dpi=100, bbox_inches='tight')
plt.show() # displays the plot
La visualisation résultante nous montrera les limites de nos polygones, en fonction des coordonnées de longitude et de latitude fournies. Nous pouvons également ajouter d'autres données à nos polygones, comme des étiquettes ou des couleurs, pour personnaliser davantage le graphique.
Approche 2 : Utilisation de la fonction map()
L'approche précédente fonctionne mieux pour les DataFrames plus petits. Une autre solution consiste à utiliser la fonction map de Python pour générer une colonne avec des polygones. Voyons maintenant comment cela peut être réalisé en utilisant notre exemple.
Tout d'abord, extrayons les coordonnées de la dataframe et stockons-les dans un tableau numpy. Nous pouvons y parvenir en sélectionnant les colonnes 'longitude_c1', 'latitude_c1', 'longitude_c2', 'latitude_c2', 'longitude_c3', 'latitude_c3', 'longitude_c4' et 'latitude_c4'. Ensuite, nous pouvons convertir cette sélection en un tableau numpy en utilisant la fonction to_numpy() :
Coords = df[ ['longitude_c1', 'latitude_c1', \
'longitude_c2', 'latitude_c2', \
'longitude_c3', 'latitude_c3', \
'longitude_c4', 'latitude_c4'] ].to_numpy()
Le code ci-dessus affichera
array([[ 2.25220e+00, 4.87566e+01, 2.25220e+00, 4.89566e+01,
2.45220e+00, 4.89566e+01, 2.45220e+00, 4.87566e+01],
[-2.27600e-01, 5.14072e+01, -2.27600e-01, 5.16072e+01,
-2.76000e-02, 5.16072e+01, -2.76000e-02, 5.14072e+01],
[ 3.75173e+01, 5.56558e+01, 3.75173e+01, 5.58558e+01,
3.77173e+01, 5.58558e+01, 3.77173e+01, 5.56558e+01],
[ 2.88784e+01, 4.09082e+01, 2.88784e+01, 4.11082e+01,
2.90784e+01, 4.11082e+01, 2.90784e+01, 4.09082e+01]])
En examinant la forme de notre matrice,
Coords.shape
, nous constatons qu'il se compose de 4 rangées avec 8 coordonnées, ce qui donne une forme de
(4, 8)
Cependant, la fonction Polygon de shapely (shapely.Polygon) nécessite que les coordonnées soient dans la forme (N,2) (voir shapely.Polygon). Pour répondre à cette exigence, nous pouvons facilement remodeler notre matrice en exécutant la ligne de code suivante:
Coords = Coords.reshape(4,4,2)
En conséquence, notre matrice a maintenant une forme de (4,4,2), ce qui signifie 4 lignes avec 4 points, chacun défini par 2 coordonnées représentant la longitude et la latitude.
Pour créer nos polygones, nous pouvons utiliser la fonction Python intégrée map() comme suit:
polygons = list(map(Polygon, Coords.tolist()))
Ce code génère une liste de quatre polygones:
[
<shapely.geometry.polygon.Polygon at 0x7f7e1014f700>,
<shapely.geometry.polygon.Polygon at 0x7f7e08f37820>,
<shapely.geometry.polygon.Polygon at 0x7f7e1014fe50>,
<shapely.geometry.polygon.Polygon at 0x7f7e1014fd90>
]
Nous pouvons utiliser cette liste pour générer une nouvelle colonne dans notre DataFrame, telle que "géométrie", qui contiendra nos polygones.
df['geometry'] = polygons
Pour afficher la DataFrame, nous pouvons utiliser la fonction print :
print(df)
Le code ci-dessus affichera
city_name longitude_c1 latitude_c1 longitude_c2 latitude_c2 \
0 Paris 2.2522 48.7566 2.2522 48.9566
1 London -0.2276 51.4072 -0.2276 51.6072
2 Moscow 37.5173 55.6558 37.5173 55.8558
3 Istanbul 28.8784 40.9082 28.8784 41.1082
longitude_c3 latitude_c3 longitude_c4 latitude_c4 \
0 2.4522 48.9566 2.4522 48.7566
1 -0.0276 51.6072 -0.0276 51.4072
2 37.7173 55.8558 37.7173 55.6558
3 29.0784 41.1082 29.0784 40.9082
geometry
0 POLYGON ((2.2522 48.7566, 2.2522 48.9566, 2.45...
1 POLYGON ((-0.2276 51.4072, -0.2276 51.6072, -0...
2 POLYGON ((37.5173 55.6558, 37.5173 55.8558, 37...
3 POLYGON ((28.8784 40.9082, 28.8784 41.1082, 29...
Cette approche peut être bénéfique pour des ensembles de données plus importants, car elle utilise la bibliothèque numpy efficace et la fonction de map intégrée.
Dans l'ensemble, il existe plusieurs façons de générer des polygones à partir d'une DataFrame contenant des coordonnées de longitude et de latitude. La méthode choisie dépendra des exigences spécifiques du projet et de la taille de l'ensemble de données.
Conversion de notre DataFrame Pandas en GeoDataFrame
Pour convertir notre DataFrame Pandas en GeoDataFrame, nous pouvons facilement y parvenir en utilisant le code suivant.
import geopandas
gdf = geopandas.GeoDataFrame(
df,
geometry=df['geometry'],
crs="EPSG:4326"
)
Ce code Python permet de convertir une DataFrame Pandas en une GeoDataFrame. Voici une explication ligne par ligne :
- import geopandas: Cette ligne importe la bibliothèque GeoPandas. GeoPandas étend les fonctionnalités de Pandas pour prendre en charge les opérations géospatiales, telles que la manipulation de données géographiques et la cartographie.
- gdf = geopandas.GeoDataFrame(df, geometry=df['geometry'], crs="EPSG:4326"): Cette ligne crée une GeoDataFrame à partir d'une DataFrame Pandas existante (df). Les paramètres passés à la fonction geopandas.GeoDataFrame() sont les suivants :
- df: C'est la DataFrame Pandas que nous voulons convertir en GeoDataFrame.
-geometry=df['geometry']: Ici, nous spécifions la colonne de df qui contient les géométries. Cela permet à GeoPandas de reconnaître quelle colonne doit être traitée comme la géométrie spatiale. - crs="EPSG:4326": Le paramètre crs (Coordinate Reference System) définit le système de coordonnées de référence pour les données. Ici, "EPSG:4326" indique que les coordonnées sont exprimées en latitude et longitude avec le système de référence WGS 84, qui est couramment utilisé pour les données géographiques.
En résumé, ce code permet de créer une GeoDataFrame à partir d'une DataFrame Pandas en spécifiant la colonne contenant les géométries et en définissant le système de coordonnées de référence. Cela permet d'utiliser les fonctionnalités géospatiales avancées de GeoPandas pour travailler avec des données géographiques.
Références
Liens | Site |
---|---|
shapely.Polygon | shapely.readthedocs.io |
map() | docs.python.org |