I have 2 data frames, let's say, df1 and df2. I need to find df1 polygons that overlay with df2 (the green line), and remove them from main dataframe df1.

I do not need to extract a overlaying part or create a new dataframe, I need to identify the ones which overlays in any cases and remove them. The result would be df1 with the removed polygons.

I tried to use GeoPandas intersect and overlay, however, could not find the solution. Both dataframes have the same coordinate system.

import pandas as pd
import geopandas as gpd

df1 = gpd.read_file(r'E:\...\dfs1.shp')
df2 = gpd.read_file(r'E:\...\dfs2.shp')

print(df1.crs, df1.crs)

res_intersection = gpd.overlay(df1, df2, how='intersection')

TypeError: keep_geom_type does not support None.

enter image description here


2 Answers 2


You can use spatial join:

import geopandas as gpd
df1 = gpd.read_file(r'/home/bera/Desktop/gistemp/greens.shp')
df2 = gpd.read_file(r'/home/bera/Desktop/gistemp/buildings.shp')
df2['savedindex']= df2.index #Save the index values as a new column

intersecting = df1.sjoin(df2, how='inner')['savedindex'] #Find the polygons that intersect. Keep savedindex as a series

df2 = df2[~df2.savedindex.isin(intersecting)] #Filter away these, "savedindex is not in intersecting"


enter image description here

  • 1
    For potential user: As I work with large datasets, execution time is important. And this definitely work much faster than the solution of new_df1 = df1.loc[df1.intersects(df2.unary_union)].reset_index(drop=True). Good luck!
    – g123456k
    Commented Dec 17, 2021 at 6:55

You can do the following:

new_df1 = df1.loc[~df1.intersects(df2.unary_union)].reset_index(drop=True)

The new_df1 GeoDataFrame will contain all the observations/rows/features from df1 that DO NOT intersect with the elements of df2.

  • 2
    Just to know, how it would be to get features from df1 that DO intersect with the elements of df2. Is it the same line, just a little modified?
    – g123456k
    Commented Dec 8, 2021 at 7:17
  • You're exactly right, the only difference is the tilde (~): new_df1 = df1.loc[df1.intersects(df2.unary_union)].reset_index(drop=True). Think of the tilde character as a element-wise NOT operator. df1.intersects(df2.unary_union) generates a pd.Series of boolean values and the tilde (~) operator just inverts them.
    – Felipe D.
    Commented Dec 8, 2021 at 15:55

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.