Looking for a way to run GeoDataFrame.sjoin() with more than one predicate. For example, on QGIS' "Join by location" tool, there is a check box of predicates to mark as needed.

When trying to run predicates as a list :

my_sjoin = gdf_1.sjoin(gdf_2, predicate=['within', 'intersects'])

The function wont accept a list:

"TypeError: unhashable type: 'list' "


1 Answer 1


As I understand it, intersects will also find the withins:

Returns True if the boundary or interior of the object intersect in any way with those of the other.

Which looks correct, A is completely within a grid cell:

import geopandas as gpd

df1 = gpd.read_file(r'/home/bera/Desktop/GIStest/grid.shp')
df2 = gpd.read_file(r'/home/bera/Desktop/GIStest/polygons.shp')

intersecting = sorted(list(set(df1.sjoin(df2, predicate='intersects')['polyid']))) #['A', 'B', 'D', 'F', 'G', 'H', 'J', 'K', 'L'] You might want a how='left' if you want to keep all features in df1
within = sorted(list(set(df2.sjoin(df1, predicate='within')['polyid']))) #['A', 'F', 'L'] #All are already above

enter image description here

Otherwise you would chain the joins, first one predicate/op, then the other

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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