Converti un DataFrame di Panda in un GeoDataFrame


42

Sembra una domanda abbastanza semplice, ma non riesco a capire come convertire un DataFrame di Panda in un GeoDataFrame per un join spaziale.

Ecco un esempio di come appaiono i miei dati usando df.head():

    Date/Time           Lat       Lon       ID
0   4/1/2014 0:11:00    40.7690   -73.9549  140
1   4/1/2014 0:17:00    40.7267   -74.0345  NaN

In realtà, questo frame di dati è stato creato da un CSV, quindi se è più facile leggere direttamente il CSV come GeoDataFrame, va bene lo stesso.


1
usa GeoPandas
gene

Risposte:


78

Converti prima il contenuto del DataFrame (ad es. LatE le Loncolonne) in appropriate geometrie Shapely e poi usali insieme al DataFrame originale per creare un GeoDataFrame.

from geopandas import GeoDataFrame
from shapely.geometry import Point

geometry = [Point(xy) for xy in zip(df.Lon, df.Lat)]
df = df.drop(['Lon', 'Lat'], axis=1)
crs = {'init': 'epsg:4326'}
gdf = GeoDataFrame(df, crs=crs, geometry=geometry)

Risultato:

    Date/Time           ID      geometry
0   4/1/2014 0:11:00    140     POINT (-73.95489999999999 40.769)
1   4/1/2014 0:17:00    NaN     POINT (-74.03449999999999 40.7267)

Dato che le geometrie spesso vengono nel formato WKT, ho pensato di includere anche un esempio per quel caso:

import geopandas as gpd
import shapely.wkt

geometry = df['wktcolumn'].map(shapely.wkt.loads)
df = df.drop('wktcolumn', axis=1)
crs = {'init': 'epsg:4326'}
gdf = gpd.GeoDataFrame(df, crs=crs, geometry=geometry)

Grazie ancora! È molto più semplice e funziona molto velocemente - molto meglio che scorrere ogni riga del file df al mio n = 500.000 :)
atkat12

6
Accidenti, grazie! Controllo questa risposta come ogni 2 giorni :)
Owen il

1
penseresti che questa sarebbe la prima voce nella documentazione!
Dominik,

+1 per shapely.wkt. Mi ci è voluto un po 'per capirlo!
StefanK,

14

One-liner! Inoltre alcuni indicatori di prestazioni per persone con big data.

Dato pandas.DataFrameche ha x Longitudine e y Latitudine in questo modo:

df.head()
x   y
0   229.617902  -73.133816
1   229.611157  -73.141299
2   229.609825  -73.142795
3   229.607159  -73.145782
4   229.605825  -73.147274

Convertiamo pandas.DataFramein a geopandas.GeoDataFramecome segue:

Importazioni di librerie e velocizzazioni formali :

import geopandas as gpd
import shapely
shapely.speedups.enable() # enabled by default from version 1.6.0

Codice + tempi di riferimento su un set di dati di test che ho in giro:

#Martin's original version:
#%timeit 1.87 s ± 7.03 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
gdf = gpd.GeoDataFrame(df.drop(['x', 'y'], axis=1),
                                crs={'init': 'epsg:4326'},
                                geometry=[shapely.geometry.Point(xy) for xy in zip(df.x, df.y)])



#Pandas apply method
#%timeit 8.59 s ± 60.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
gdf = gpd.GeoDataFrame(df.drop(['x', 'y'], axis=1),
                       crs={'init': 'epsg:4326'},
                       geometry=df.apply(lambda row: shapely.geometry.Point((row.x, row.y)), axis=1))

L'uso pandas.applyè sorprendentemente più lento, ma potrebbe adattarsi meglio ad altri flussi di lavoro (ad es. Su set di dati più grandi che utilizzano la libreria dask):

Crediti a:

Alcuni riferimenti Work-In-Progress (a partire dal 2017) per la gestione di grandi daskset di dati:


Grazie per il confronto, infatti la versione zip è molto più veloce
MCMZL
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.