Extracting Point Coordinates from a SEDF: Using the ArcGIS API for Python and a Spatially Enabled Data Frame (SEDF) I would like to know if there is an easy way similar to using GeoPandas to extract the x and y coordinates of points (census tract centroids) and assign them to new items/variables? For instance in GeoPandas:
df_tract['XC'] = df_tract.geometry.x and df_tract['YC'] = df_tract.geometry.y
This will produce an Attribute Error: 'DataFrame' object has no attribute 'geometry'
I know the SEDF stores geometry as a SHAPE dictionary and have tried various direct ways to get these coordinated short of iterating through the distionary such as:
df_tract['XC'] = df_tract.get("x") and df_tract['YC'] = df_tract.get("y")
No error this way but resulting values are None
I am slowly becoming more familar with using Python so any suggestions would be greatly appreciated.
There are several ways to get the centroid and hence, the X and Y coordinates
Other options can be found looking in the api's help
Hi Dan, thanks for the suggestions about how to calculate centroids from a SEDF. However, my problem is somewhat different. The SEDF was created from an existing point-based feature class that are (already consists of) centroids or mostly required equivalents (New Mexico census tract post office locations in a populated place and centroids of tracts with no P.O.). These are being used for calculating a healthcare related gravity model (access to primary care physicians, etc.). This gravity model has already been implemented using Python - GeoPandas (Jupyter Notebook) R, and originally with SAS. I was just investigating if it could now be implemented using the ArcGIS API and the new SEDF within an ArcGIS Pro Notebook. It was very easy to extract the existing point (centroid, etc.) coordinates from the geometry contained in a GeoPandas data frame. But, it does not seem to be that straight forward from a SEDF SHAPE. Perhaps this method could be implemented in a subsequent SEDF release to work similar to how easy it is with GeoPandas. I could always just use an ArcGIS Desktop or Pro to add the coordinates (from the geometry tokens SHAPE@X and SHAPE@Y) to the feature class first and then create the SEDF for later use. Still open to learning a more direct way if possible?
Larry Spear M.A., GISP Phone: (505) 508-5942
Sr. Research Scientist (Ret.) Cell: (505) 401-5756
Division of Government Research Email: firstname.lastname@example.org<mailto:email@example.com>
Non-degree Graduate Student URL: http://www.unm.edu/~lspear
University of New Mexico
Albuquerque, New Mexico 87131
I use numpy (which pandas largely depends on) for all my shape and attribute work. Point geometry is easy with FeatureClassToNumPyArray. Attributes are a snap with TableToNumPyArray. The attribute column extraction is the same someArray['SomeField'].
I have many, many blog posts on numpy's use in GIS
They are ones I wrote in my previous incarnation as a faculty member before I retired.
My new incarnation posts ArcGIS Pro and numpy tools at
Thanks again! I used FeatureClassToNumPyArray to get the point coordinates then created a pandas data frame from the numpy array and merged it with the SEDF to create a new SEDF and got what I wanted. Not as direct as in GeoPandas but it will work.
Get the NM census tract with provider Feature Class (CT 2002)
Note: Projection already EPSG: 26913 (NAD83 / UTM zone 13N)
Also Create a Spatially Enabled Data Frame (SEDF) and Numeric GEOIDN
ct_tract_pt_lyr = "ct2002exp_t1"
nmctpp = pd.DataFrame.spatial.from_featureclass(ct_tract_pt_lyr)
nmctpp['GEOIDN'] = pd.to_numeric(nmctpp['GEOID'])
Extract the point (place and centroid) coordinates
ct_coords_array = arcpy.da.FeatureClassToNumPyArray(ct_tract_pt_lyr, (["OID@", "SHAPE@X", "SHAPE@Y"]))
Create a Pandas DataFrame from NumPy Array
ct_coords_df = pd.DataFrame(data=ct_coords_array, index=None, columns=None)
ct_coords_df['OBJECTID'] = ct_coords_df['OID@']
Merge the coordinates on to a new SEDF
nmctppc = nmctpp.merge(ct_coords_df, on = 'OBJECTID')
Saw this a tad late but here is another way to go about it.
ArcGIS API for python has elaborate methods to extract centroids. Refer to this document
If you have your content on AGOL
from arcgis.gis import GIS import arcgis from arcgis import features from arcgis.features import GeoAccessor, GeoSeriesAccessor, FeatureLayer from arcgis import geometry from arcgis.features.find_locations import find_centroids #sign in portal gis = GIS("https://url.arcgis.com", "UserName", "Password") #Feature Service item=gis.content.get('Feature_Service_ID') l=item.layers #Generate Centroids. PLEASE NOTE THEY WILL BE PUBLISHED ON PORTAL poly_to_point = find_centroids(l, output_name="Centroids")
You can then generate and tabulate the geometry
# for points sdf['YCoord'] = sdf['SHAPE'].apply(lambda shape: shape.y) sdf['XCoord'] = sdf['SHAPE'].apply(lambda shape: shape.x) # for polygons sdf['YCoord'] = sdf['SHAPE'].apply(lambda shape: shape.centroid) sdf['XCoord'] = sdf['SHAPE'].apply(lambda shape: shape.centroid)
A nother way to do it would be;
sdf=sdf.assign(longitude=sdf.SHAPE.astype(str).apply(lambda x: Point(x)\ .coordinates()).str,latitude=sdf.SHAPE.astype(str).\ apply(lambda x: Point(x).coordinates()).str)
One solution i could think of to achieve this with ArcGIS Python API.
1. export the sedf into FeatureSet
2. get features from FeatureSet
3. get geometry from the feature
4. get centroid with the geometry's centroid property