29

I have a geopandas df with a column of shapely point objects. I want to extract the coordinate (lat/lon) from the shapely point objects to generate latitude and longitude columns. There must be an easy way to do this, but I cannot figure it out.

I know you can extract the individual coordinates like this:

lon = df.point_object[0].x
lat = df.point_object[0].y

And I could create a function that does this for the entire df, but I figured there was a more efficient/elegant way.

Georgy
  • 12,464
  • 7
  • 65
  • 73
jtam
  • 814
  • 1
  • 8
  • 24

3 Answers3

37

If you have the latest version of geopandas (0.3.0 as of writing), and the if df is a GeoDataFrame, you can use the x and y attributes on the geometry column:

df['lon'] = df.point_object.x
df['lat'] = df.point_object.y

In general, if you have a column of shapely objects, you can also use apply to do what you can do on individual coordinates for the full column:

df['lon'] = df.point_object.apply(lambda p: p.x)
df['lat'] = df.point_object.apply(lambda p: p.y)
joris
  • 133,120
  • 36
  • 247
  • 202
  • 1
    I must not have the latest version because the first solution is giving me an error. But the second solution works great. Thanks! – jtam Apr 03 '18 at 17:06
  • Hi, it's been a while since you answered. I tried the methods you suggested but it fails with error code `IndexError: index out of range`. Does this not work with `GeoSeries`? – baggiponte Nov 09 '21 at 08:24
  • edit: calling the attribute `geodataframe.point_object.x/y/z` will return error if there are empty geometries (see [here](https://github.com/geopandas/geopandas/issues/2223)) – baggiponte Nov 09 '21 at 09:07
21

Without having to iterate over the Dataframe, you can do the following:

df['lon'] = df['geometry'].x
df['lat'] = df['geometry'].y
Mandi
  • 311
  • 2
  • 3
  • 2
    I've gotten this to work before, but sometimes (with no apparent difference in the data structure) I get `AttributeError: 'Series' object has no attribute 'x'` – Aaron Bramson Jun 14 '21 at 09:09
  • 1
    this works in one go `df[['lat', 'lng']] = df.apply(lambda p: (p.geometry.y, p.geometry.x), axis=1, result_type='expand')` – adrien Mar 11 '22 at 08:15
  • I wonder which is fastest, doing both columns separately as in this answer, doing them separately as lambdas on series, or doing them together as a lambda on the dataframe. – Aaron Bramson Feb 09 '23 at 09:47
2

The solution to extract the center point (latitude and longitude) from the polygon and multi-polygon.

import geopandas as gpd
df = gpd.read_file(path + 'df.geojson')
#Find the center point
df['Center_point'] = df['geometry'].centroid
#Extract lat and lon from the centerpoint
df["long"] = df.Center_point.map(lambda p: p.x)
df["lat"] = df.Center_point.map(lambda p: p.y)
Kum_R
  • 368
  • 2
  • 19