Introduction
If you are working with geospatial data, chances are you have encountered the GeoSeries
or GeoDataFrame
object error at some point. This is a common issue that many people face when using these objects in Python.
First, it's important to understand why this error occurs. The GeoSeries
and GeoDataFrame
objects are part of the popular geospatial library - GeoPandas. These objects contain various geometric data structures, such as points, lines, and polygons.
When we encounter the 'GeoSeries' or 'GeoDataFrame' object has no attribute 'geoms'
error, it means that we are trying to access a geometric attribute that does not exist in our data.
Most frequent reason why this error might occur
There can be several reasons why this error might occur. The most frequent reason is attempting to apply geoms to GeoSeries
or GeoDataFrame
objects instead of a shapely geometry multipolygon. For example, when executing the code
my_variable.geoms
, the resulting output is...
AttributeError: 'GeoSeries' object has no attribute 'geoms'
or
AttributeError: 'GeoDataFrame' object has no attribute 'geoms'
Please attempt:
type(my_variable)
you should get
geopandas.geoseries.GeoSeries
or
geopandas.geodataframe.GeoDataFrame
How to Fix It
To resolve the issue, it is usually straightforward. Firstly, you need to extract the multipolygon from the GeoSeries or GeoDataFrame.
my_variable.iloc[0]
check the type
type(my_variable.iloc[0])
should give
shapely.geometry.multipolygon.MultiPolygon
and then apply geoms
my_variable.iloc[0].geoms
Example of case
Allow me to present an example where I encountered an error message for the first time and provide you with a solution to resolve it.
Let's consider the following geopandas dataframe
import pandas as pd
import geopandas as gpd
df = pd.DataFrame(
{
"City": ["Paris", "New-York", "London", "Marseille", "Dijon", "Bordeaux"],
"Latitude": [48.8566, 40.7128, 51.5072, 43.2965, 47.3220, 44.8378],
"Longitude": [2.3522, -74.0060, -0.1276, 5.3698, 5.0415, -0.5792],
}
)
gdf = gpd.GeoDataFrame(
df, geometry=gpd.points_from_xy(df.Longitude, df.Latitude), crs="EPSG:4326"
)
gives
City Latitude Longitude geometry
0 Paris 48.8566 2.3522 POINT (2.35220 48.85660)
1 New-York 40.7128 -74.0060 POINT (-74.00600 40.71280)
2 London 51.5072 -0.1276 POINT (-0.12760 51.50720)
3 Marseille 43.2965 5.3698 POINT (5.36980 43.29650)
4 Dijon 47.3220 5.0415 POINT (5.04150 47.32200)
5 Bordeaux 44.8378 -0.5792 POINT (-0.57920 44.83780)
Our goal is to narrow down this dataframe to include only cities located in France. We will be using a polygon of France to filter the cities that fall within its boundaries (see previous article How to filter a geopandas dataframe for points that fall within a specified polygon ?).
Extract France Geometries using Natural Earth Data (see How to retrieve country name for a given latitude and longitude using geopandas and naturalearthdata ? ):
df_110m_cultural = gpd.read_file('110m_cultural')
df_110m_cultural[ df_110m_cultural[ 'ADMIN' ] == 'France' ]
Now if we try
df_110m_cultural[ df_110m_cultural[ 'ADMIN' ] == 'France' ]['geometry'].geoms
we will get
AttributeError: 'GeoSeries' object has no attribute 'geoms'
since
type(df_110m_cultural[ df_110m_cultural[ 'ADMIN' ] == 'France' ]['geometry'])
returns
geopandas.geoseries.GeoSeries
How to fix it:
fr_geometries = df_110m_cultural['geometry'][ df_110m_cultural[ 'ADMIN' ] == 'France' ]
len(fr_geometries.iloc[0])
Output
3
And
type(fr_geometries.iloc[0])
Output
shapely.geometry.multipolygon.MultiPolygon
Extract France geometries
geoms = [g for g in fr_geometries.iloc[0].geoms]
France Metropolitan:
gdf.within( geoms[1] )
Output
0 True
1 False
2 False
3 True
4 True
5 True
dtype: bool
References
Links | Site |
---|---|
shapely.MultiPolygon | shapely.readthedocs.io |
How to filter a geopandas dataframe for points that fall within a specified polygon ? | en.moonbooks.org |
How to retrieve country name for a given latitude and longitude using geopandas and naturalearthdata ? | en.moonbooks.org |