Let's say I have two disjoint groups / "islands" of polygons (think census tracts in two non-adjacent counties). My data could look something like this: >>> p1=Polygon([(0,0),(10,0),(10,10),(0,10)]) >>> p2=Polygon([(10,10),(20,10),(20,20),(10,20)]) >>> p3=Polygon([(10,10),(10,20),(0,10)]) >>> >>> p4=Polygon([(40,40),(50,40),(50,30),(40,30)]) >>> p5=Polygon([(40,40),(50,40),(50,50),(40,50)]) >>> p6=Polygon([(40,40),(40,50),(30,50)]) >>> >>> df=gpd.GeoDataFrame(geometry=[p1,p2,p3,p4,p5,p6]) >>> df geometry 0 POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0)) 1 POLYGON ((10 10, 20 10, 20 20, 10 20, 10 10)) 2 POLYGON ((10 10, 10 20, 0 10, 10 10)) 3 POLYGON ((40 40, 50 40, 50 30, 40 30, 40 40)) 4 POLYGON ((40 40, 50 40, 50 50, 40 50, 40 40)) 5 POLYGON ((40 40, 40 50, 30 50, 40 40)) >>> >>> df.plot() I want the polygons within each island to take on an ID (can be arbitrary) representing it's group. For example the 3 polygons on the bottom left can have IslandID = 1 and the 3 polygons on the top right can have an IslandID=2. I have developed a way to do this, but I'm wondering if it's the best / most efficient way. I do the following: 1) Create a GeoDataFrame with a geometry equal to polygons within the multipolygon unary union. This gives me two polygons, one for each "island". >>> SepIslands=gpd.GeoDataFrame(geometry=list(df.unary_union)) >>> SepIslands.plot() 2) Create an ID for each group. >>> SepIslands['IslandID']=SepIslands.index+1 3) Spatial join the islands to the original polygons, so each polygon has the appropriate island id. >>> Final=gpd.tools.sjoin(df, SepIslands, how='left').drop('index_right',1) >>> Final geometry IslandID 0 POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0)) 1 1 POLYGON ((10 10, 20 10, 20 20, 10 20, 10 10)) 1 2 POLYGON ((10 10, 10 20, 0 10, 10 10)) 1 3 POLYGON ((40 40, 50 40, 50 30, 40 30, 40 40)) 2 4 POLYGON ((40 40, 50 40, 50 50, 40 50, 40 40)) 2 5 POLYGON ((40 40, 40 50, 30 50, 40 40)) 2 Is this indeed the best / most efficient way to do this? Continue reading...