Update 201912: The official documentation at https://geopandas.readthedocs.io/en/latest/gallery/create_geopandas_from_pandas.html does it succinctly using geopandas.points_from_xy
like so:
gdf = geopandas.GeoDataFrame(
df, geometry=geopandas.points_from_xy(x=df.Longitude, y=df.Latitude)
)
You can also set a crs
or z
(e.g. elevation) value if you want.
Old Method: Using shapely
One-liners! Plus some performance pointers for big-data people.
Given a pandas.DataFrame
that has x Longitude and y Latitude like so:
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
Let's convert the pandas.DataFrame
into a geopandas.GeoDataFrame
as follows:
Library imports and shapely speedups:
import geopandas as gpd
import shapely
shapely.speedups.enable() # enabled by default from version 1.6.0
Code + benchmark times on a test dataset I have lying around:
#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))
Using pandas.apply
is surprisingly slower, but may be a better fit for some other workflows (e.g. on bigger datasets using dask library):
Credits to:
Some Work-In-Progress references (as of 2017) for handling big dask
datasets: