Comment créer une GeoPandas DataFrame à partir d'une DataFrame Pandas contenant des polygones ?

Published: 21 février 2024

Tags: Python; Geopandas;

DMCA.com Protection Status

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