Skip to content

Instantly share code, notes, and snippets.

@mhweber
Forked from debboutr/explode.py
Created July 25, 2016 17:45
Show Gist options
  • Star 27 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save mhweber/cf36bb4e09df9deee5eb54dc6be74d26 to your computer and use it in GitHub Desktop.
Save mhweber/cf36bb4e09df9deee5eb54dc6be74d26 to your computer and use it in GitHub Desktop.
Explode MultiPolygon geometry into individual Polygon geometries in a shapefile using GeoPandas and Shapely
import geopands as gpd
from shapely.geometry.polygon import Polygon
from shapely.geometry.multipolygon import MultiPolygon
def explode(indata):
indf = gpd.GeoDataFrame.from_file(indata)
outdf = gpd.GeoDataFrame(columns=indf.columns)
for idx, row in indf.iterrows():
if type(row.geometry) == Polygon:
outdf = outdf.append(row,ignore_index=True)
if type(row.geometry) == MultiPolygon:
multdf = gpd.GeoDataFrame(columns=indf.columns)
recs = len(row.geometry)
multdf = multdf.append([row]*recs,ignore_index=True)
for geom in range(recs):
multdf.loc[geom,'geometry'] = row.geometry[geom]
outdf = outdf.append(multdf,ignore_index=True)
return outdf
@alemosie
Copy link

alemosie commented Feb 19, 2017

Thanks so much for this -- solved a pesky problem I was having when getting "inf" values from a CRS conversion with multipolygons!

@3vivekb
Copy link

3vivekb commented Sep 23, 2017

This is great. Geopandas is misspelled though.

@ianashpole
Copy link

I created an account just to say: This is GREAT. Has solved a massive headache for me. Thanks very much!

@rutgerhofste
Copy link

rutgerhofste commented Feb 16, 2018

This is great but not so fast. Below will potentially speed up the process:

def explode(gdf):
    """ 
    Explodes a geodataframe 
    
    Will explode muti-part geometries into single geometries. Original index is
    stored in column level_0 and zero-based count of geometries per multi-
    geometry is stored in level_1
    
    Args:
        gdf (gpd.GeoDataFrame) : input geodataframe with multi-geometries
        
    Returns:
        gdf (gpd.GeoDataFrame) : exploded geodataframe with a new index 
                                 and two new columns: level_0 and level_1
        
    """
    gs = gdf.explode()
    gdf2 = gs.reset_index().rename(columns={0: 'geometry'})
    gdf_out = gdf2.merge(gdf.drop('geometry', axis=1), left_on='level_0', right_index=True)
    gdf_out = gdf_out.set_index(['level_0', 'level_1']).set_geometry('geometry')
    gdf_out.crs = gdf.crs
    return gdf_out

@keithfma
Copy link

In case others find their way here, geopandas has this feature built in now:

https://www.pydoc.io/pypi/geopandas-0.4.0/autoapi/geodataframe/index.html#geodataframe.GeoDataFrame.explode

@Jwely
Copy link

Jwely commented Jul 30, 2019

Thanks @keithfma, even knowing that this feature is now built in, custom solutions like this one still dominate the first page of google results and I couldn't find the reference!

@andresjcuberli
Copy link

Thanks a lot!

@wxyang007
Copy link

Thanks so much!

@owvarley
Copy link

Thank you for this, very helpful! Thanks @keithfma for the info on it being included in geopanda. I couldn't find anything but dissolve in their docs when searching.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment