Convertir un DataFrame de pandas en un GeoDataFrame

33

Esto parece una pregunta bastante simple, pero no puedo descubrir cómo convertir un DataFrame de pandas en un GeoDataFrame para una unión espacial.

Este es un ejemplo de cómo se ven mis datos 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

De hecho, este marco de datos se creó a partir de un CSV, por lo que si es más fácil leer el CSV directamente como un GeoDataFrame, también está bien.

    
pregunta atkat12 16.12.2015 - 22:14

2 respuestas

66

Convierta el contenido de DataFrame (por ejemplo, Lat y Lon columnas) en las geometrías Shapely apropiadas y luego use junto con el DataFrame original para crear 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)

Resultado:

    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)

Dado que las geometrías a menudo vienen en formato WKT, pensé que también incluiría un ejemplo para ese 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)
    
respondido por el Martin Valgur 16.12.2015 - 22:39
8

¡Una sola línea! Además de algunos punteros de rendimiento para personas de big data.

Dado un pandas.DataFrame que tiene x Longitud y y Latitud así:

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

Convirtamos pandas.DataFrame en geopandas.GeoDataFrame de la siguiente manera:

Importaciones de bibliotecas y mejoras de forma bien formadas :

import geopandas as gpd
import shapely
shapely.speedups.enable()

Código + tiempos de referencia en un conjunto de datos de prueba que tengo por ahí:

#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))

El uso de pandas.apply es sorprendentemente más lento, pero puede ser mejor para otros flujos de trabajo (por ejemplo, en conjuntos de datos más grandes que utilizan la biblioteca dask):

Créditos a:

Algunas referencias de Work-In-Progress (a partir de 2017) para el manejo de grandes conjuntos de datos dask :

respondido por el weiji14 13.10.2017 - 04:29

Lea otras preguntas en las etiquetas