GeoPandas: return lat and long of a centroid point

Ran into this problem myself. If you want the x and y as separate GeoDataFrame columns, then this works nicely:

gdf["x"] = gdf.centroid.map(lambda p: p.x)
gdf["y"] = gdf.centroid.map(lambda p: p.y)

Starting with GeoPandas 0.3.0, you can use the provided x and y properties instead:

gdf["x"] = gdf.centroid.x
gdf["y"] = gdf.centroid.y

Leaving the rest below, but the main thing was accessing the geometry properly. If iterating over rows, e.g. for index, row in zones.iterrows(): you can simply use row.geometry.centroid.x and row.geometry.centroid.y. Geometry is a special column included in a GeoDataFrame, so every row has a geometry attribute.
You are accessing that attribute, which contains a shapely object. That shapely object will have an attribute, centroid that, in turn contains a shapely.geometry.Point, which has attributes x and y, finally giving you the properties you want.


(This part was the original effort to get to x,y with map and shapely.geometry.Point.)
I am going to assume you want a list of (x, y) tuples? Create a quick accessor function for the x and y attributes on a Point and use map.

Edit: Okay, figured out that you may be accessing the geometry in the GeoDataFrame in an incorrect way. Geometry is a column in your GeoDataFrame, which by itself produces a series. Calling centroid on that column should give you a new GeoSeries of only those centroids. I suspect the way you were going about things was taking the centroid of every vertex in each polygon. Still cannot test this since I cannot install GeoPandas right now.

def getXY(pt):
    return (pt.x, pt.y)
centroidseries = zones['geometry'].centroid
centroidlist = map(getXY, centroidseries)

or if you want two separate lists of x and y coordinates

def getXY(pt):
    return (pt.x, pt.y)
centroidseries = zones['geometry'].centroid
x,y = [list(t) for t in zip(*map(getXY, centroidseries))]

Alternately, you should also be able to use zones.geometry.centroid instead of zones['geometry'].centroid. Either way, I think calling zones.centroid may be returning a GeoDataFrame instead of a GeoSeries, giving you the unexpected output when you wrap it in another GeoSeries.


This has been made easier as of GeoPandas 0.3.0.

You can now access x and y of shapely Points inside a geopandas GeoSeries using your_GeoDataFrame.geometry.x and your_GeoDataFrame.geometry.y

(Note : I'm using python 3.6.1, not sure about behavior in 2.7, sorry)

Source on github