I would like to return the
yfrom the point object in the following series as I plan to link them with an API I built that links OSM and NetworkX. The centroids will be added as new nodes for network analysis.
gp.GeoSeries(zones.centroid).yas outlined in docs raise
AttributeError: 'GeoSeries' object has no attribute 'x'error.
Modifying things a bit and printing
list(gp.GeoSeries(zones.centroid))return thousands of shapely points of the following format:
, , , , , , , ]
The code I'm using is the following:
import geopandas as gp zones = gp.GeoDataFrame.from_file(shp_file) for index, row in zones.iterrows(): print index, gp.GeoSeries(zones.centroid) # result: # 9700022.00 POINT (-122.8196050489696 54.00617624128658) # 9700023.00 POINT (-122.7474362519174 53.99998921974029) # 9700100.00 POINT (-121.4904983300892 53.98447191612864) # 9700101.00 POINT (-122.5513619751679 53.73999791511078) # 9700102.00 POINT (-123.0624037191615 53.62317549646422) # 9700103.00 POINT (-123.0848175548173 54.05921695782788)
How can I return the
yfrom the GeoPandas POINT object?
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.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
shapelyobject will have an attribute,
centroidthat, in turn contains a
shapely.geometry.Point, which has attributes
y, finally giving you the properties you want.
(This part was the original effort to get to x,y with
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
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
centroidon 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. Either way, I think calling
zones.centroidmay be returning a GeoDataFrame instead of a GeoSeries, giving you the unexpected output when you wrap it in another GeoSeries.
Ran into this problem myself. If you want the
yas 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
gdf["x"] = gdf.centroid.x gdf["y"] = gdf.centroid.y
This has been made easier as of GeoPandas 0.3.0.
You can now access
shapely Pointsinside a
(Note : I'm using python 3.6.1, not sure about behavior in 2.7, sorry)
Source on github
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["lat"] = df.Center_point.map(lambda p: p.x) df["long"] = df.Center_point.map(lambda p: p.y)
I ran into a similar problem, only using polygon geometries and found this solution worked well for me, mind you it's using Python-3.6 so it may not work for Python-2.7.
import geopandas as gpd zones = gpd.read_file('file_to_read.shp') for i in range(0,len(zones)): zones.loc[i,'centroid_lon'] = zones.geometry.centroid.x.iloc[i] zones.loc[i,'centroid_lat'] = zones.geometry.centroid.y.iloc[i]
if you just want a numpy array of centroids:
centroids = np.vstack([df.centroid.x, df.centroid.y]).T
or as a dataframe with extra columns (i.e name for example):
pd.DataFrame(np.vstack([df.name, df.centroid.x, df.centroid.y]).T, columns=['name', 'x', 'y'])
name geometry 0 1 POLYGON ((0.00000 1.00000, 0.00000 0.00000, 1… 1 2 POLYGON ((2.00000 1.00000, 2.00000 0.00000, 3… # ==> # np.vstack([df.centroid.x, df.centroid.y]).T # array([[0.5, 0.5], # [2.5, 0.5]])
Here's a quick
df = pd.read_csv('data/hospitals.csv') df.columns # 'Ownership', 'Lat', 'Long' from shapely.geometry import Point df['geometry'] = df.apply(lambda row: Point(row.Long,row.Lat),axis=1)
Then recreate the dataframe with geopandas
gdf = gpd.DataFrame(df) # creates geodataframe with Point geometry