[Python] Identify unique groupings of polygons in Geopandas / Shapely

Discussão em 'Python' iniciado por Stack, Julho 20, 2025.

  1. Stack

    Stack Membro Participativo

    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()


    [​IMG]

    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()


    [​IMG]

    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...

Compartilhe esta Página