0

I'm trying to group rows of a GeoDataFrame based on a common gid value and aggregating two columns for which the values differ but I am facing this error:

TypeError Traceback (most recent call last)

/usr/local/lib/python3.6/dist-packages/pandas/core/algorithms.py in safe_sort(values, codes, na_sentinel, assume_unique, verify)

/usr/local/lib/python3.6/dist-packages/pandas/core/sorting.py in nargsort(items, kind, ascending, na_position, key)

/usr/local/lib/python3.6/dist-packages/geopandas/array.py in _values_for_argsort(self)

TypeError: geometries are not orderable

During handling of the above exception, another exception occurred:

(...)

/usr/local/lib/python3.6/dist-packages/numpy/core/fromnumeric.py in sort(a, axis, kind, order)

TypeError: '<' not supported between instances of 'Point' and 'Point'

Here is the full stack trace: https://pastebin.com/raw/Xbvr5CQT

And here's a piece of reproducible code:

import pandas as pd
import geopandas as gpd
import shapely
from shapely import wkt
from shapely.geometry import MultiPolygon

print(pd.__version__)      # prints 1.1.4
print(gpd.__version__)     # prints 0.8.2
print(shapely.__version__) # prints 1.7.1

# this dataframe has plenty of other attributes (not shown here),
# but they are always the same for the same gid, I only kept 
# the city-attribute one for the purpose of the example:    
df = pd.DataFrame(
    {'gid': [1,1,1,2,2],
     'city': ['Turtig', 'Zurich', 'Zuerich', 'Bern', 'Berne'],
     'city-attribute': ['blue','blue','blue','red','red'],
     'language': ['R','F','D','D','F',],
     'latitude': [47.37536, 47.37536, 47.37536, 46.95558, 46.95558, ],
     'longitude': [8.53764, 8.53764, 8.53764, 7.43863, 7.43863, ],
     })
gdf0 = gpd.GeoDataFrame(df, geometry = gpd.points_from_xy(df['longitude'], df['latitude']))
shape = MultiPolygon(wkt.loads(u'MULTIPOLYGON(((46.2015 6.1463, 46.2215 6.1463, 46.2215 6.1563, 46.20155 6.15630, 46.2015 6.1463)))'))
gdf = gdf0.append({'gid': 3, 'city':'Genève', 'city-attribute': 'yellow', 'language':'F', 'geometry':shape}, ignore_index=True)
gdf.drop(columns=['latitude', 'longitude'], inplace=True)
gdf['wkt'] = gdf['geometry'].apply(lambda x: x.wkt) # fun fact, with a WKT string it's working
gdf

the GeoDataFrame

and this is the buggy part which raises the error:

gdf_grouped = gdf.groupby(
    by=[e for e in gdf.columns if e not in ('city','language')],
    axis=0,
    as_index=False,
    dropna=False
).aggregate({
    'city': lambda x: tuple(x),
    'language': lambda x: tuple(x)
})

Anyone already met (and hopefully solved) this issue?

Please, notice that if I drop the geometry column prior to that code, it is working fine:

gdf.drop(columns=['geometry'], inplace=True)
# the buggy block of code
gdf_grouped

which leads to the following GeoDataFrame:

the grouped GeoDataFrame

3
  • This probably has to do with including the shape field in your group by (or at least, you’re not explicitly leaving it out of the grouping). You need to aggregate your geometries or not include it in the grouping.
    – jesnes
    Jun 24 at 18:46
  • There is an open issue on github discussing this issue, and then it looks like a fix may have been implemented in the latest version (maybe only the development version). But the problem of how to merge topologically equivalent, but not identically defined shapely objects still stands and it looks like a fix isn't coming soon. you're better off leaving it out and then adding the shape back in (check out dissolve) after your groupby. Jun 25 at 7:46
  • Exclude geometry column from by
    – BERA
    Jun 25 at 11:26
1

TypeError: '<' not supported between instances of 'Point' and 'Point'

is telling you that shapely.Point object are not supporting the "<" operator. this operator is used by Geopandas to order or group.

simply drop the geometry column and then aggregate the point together:

from shapely.ops import unary_union

gdf_grouped = gdf.groupby(
    by=[e for e in gdf.columns if e not in ('city','language', 'geometry')],
    axis=0,
    as_index=False,
    dropna=False
).aggregate({
    'city': lambda x: tuple(x),
    'language': lambda x: tuple(x),
    'geometry': lambda x: unary_union(x)
})

gdf_grouped
1
  • I'm actually using lambda x: x.iloc[0] or lambda x: x.unique()[0] as workarounds, which also work in my case. Jul 6 at 19:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.