Saltar al contenido

Convertir Pandas DataFrame a GeoDataFrame

Nuestros mejores investigadores han agotado sus provisiones de café, por su búsqueda a tiempo completo por la solución, hasta que América halló el arreglo en Bitbucket y hoy la comparte aquí.

Solución:

Convierta el contenido del DataFrame (p. ej. Lat y Lon columnas) en geometrías Shapely apropiadas primero y luego úselas 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)
gdf = GeoDataFrame(df, crs="EPSG:4326", 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é en incluir un ejemplo para ese caso también:

import geopandas as gpd
import shapely.wkt

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

Actualización 201912: la documentación oficial en https://geopandas.readthedocs.io/en/latest/gallery/create_geopandas_from_pandas.html lo hace de manera sucinta usando geopandas.points_from_xy al igual que:

gdf = geopandas.GeoDataFrame(
    df, geometry=geopandas.points_from_xy(x=df.Longitude, y=df.Latitude)
)

También puede establecer un crs o z (por ejemplo, elevación) valor si lo desea.


Método antiguo: usar bien formado

¡De una sola línea! Además de algunos indicadores de rendimiento para la gente 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 el pandas.DataFrame en un geopandas.GeoDataFrame como sigue:

Importaciones de bibliotecas y aceleraciones bien formadas:

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

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

Usando pandas.apply es sorprendentemente más lento, pero puede adaptarse mejor a otros flujos de trabajo (por ejemplo, en conjuntos de datos más grandes que usan la biblioteca dask):

Créditos para:

  • ¿Hacer un archivo de forma a partir del marco de datos de Pandas? (para el método de aplicación de pandas)
  • Acelere el punto de fila en el polígono con Geopandas (para la sugerencia de aceleración)

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

  • http://matthewrocklin.com/blog/work/2017/09/21/accelerating-geopandas-1
  • https://github.com/geopandas/geopandas/issues/461
  • https://github.com/mrocklin/dask-geopandas

Reseñas y valoraciones

Recuerda que te permitimos decir si te ayudó.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *