3

I have a GeoDataframe containing the spatially joined result of a square grid map and flood hazard data. However, there are instances of rows with the same "geometry" but differing "flood_score" data (because of the spatial join intersection). How do I keep only the max "flood_score" data for each unique "geometry"?

enter image description here

I've tried the code below:

test = mrkna_grid.dissolve(by='flood_score', aggfunc='max')

However, it only returns 4 rows (as opposed to thousands) and grouped it by the "flood_score".

enter image description here

Essentially, I want to do this, but it doesn't work with "geometry":

df.loc[df.reset_index().groupby(['geometry'])['flood_score'].idxmax()]
3
  • I'm slightly confused by what column it is exactly you're wanting to group the dataframe by. Can you give an example of your desired output? You have specifically asked the dataframe to be grouped by flood score
    – Joe Be
    Oct 28, 2021 at 8:59
  • @JoeBe I want to group them by the geometry, getting only the maximum flood_score. When I spatially joined the two maps, it resulted in duplicate geometry data with different flood_score values. For example, there are two rows with geometry x, but with different flood_score data because they both intersected. I only want one instance of geometry x that has the maximum of the flood_score data.
    – SS-Salt
    Oct 28, 2021 at 9:02
  • @Taras The row count has been decreased to the same amount before the spatial join, indicating that the duplicates have been removed. If the function drop_duplicates drops rows from a top-down order based on the sorted dataframe, then this should be correct. You can post this as an answer and I'll mark it. Thank you!
    – SS-Salt
    Oct 28, 2021 at 9:32

2 Answers 2

2

Let's assume there is polygon layer (a shapefile) with the following attribute table, see image below

input

With this code I am loading this shapefile into a GeoDataFrame

import geopandas as gpd

file = "P:/Test/qgis_test/test_for_geopandas.shp"

gdf = gpd.read_file(file)
print(gdf)

The GeoDataFrame itself

    fid  ...                                           geometry
0   6.0  ...  POLYGON ((233499.352 5752838.208, 559980.331 5...
1   7.0  ...  POLYGON ((233499.352 5752838.208, 559980.331 5...
2   8.0  ...  POLYGON ((233499.352 5752838.208, 559980.331 5...
3   9.0  ...  POLYGON ((978501.160 5695530.377, 1164317.462 ...
4  10.0  ...  POLYGON ((978501.160 5695530.377, 1164317.462 ...
5  11.0  ...  POLYGON ((978501.160 5695530.377, 1164317.462 ...
6  12.0  ...  POLYGON ((978501.160 5695530.377, 1164317.462 ...
7  13.0  ...  POLYGON ((978501.160 5695530.377, 1164317.462 ...
8  14.0  ...  POLYGON ((978501.160 5695530.377, 1164317.462 ...
9  15.0  ...  POLYGON ((485306.490 4940108.963, 681542.397 5...

[10 rows x 4 columns]

With the following code, it is possible to keep only the max "flood_score" data for each unique geometry.

gdf_ = gdf.sort_values('flood_scor', ascending=False).drop_duplicates(['geometry'])
print(gdf_)

The output GeoDataFrame will look like:

    fid  ...                                           geometry
8  14.0  ...  POLYGON ((978501.160 5695530.377, 1164317.462 ...
1   7.0  ...  POLYGON ((233499.352 5752838.208, 559980.331 5...
9  15.0  ...  POLYGON ((485306.490 4940108.963, 681542.397 5...

[3 rows x 4 columns]
1

If the geometries are identical, you dont need to dissolve, just drop the duplicates:

import geopandas as gpd

df = gpd.read_file(r'C:\GIS\data\tempdata\my.shp')
df['wkt'] = df.geometry.apply(lambda x: x.to_wkt()) #Create a wkt string column

df = df.sort_values(by='flood_source') #Sort by flood_source
df = df.drop_duplicates(subset=['wkt'], keep='last') #Drop duplicate wkt keep last/largest flood source value

df.to_file(r'C:\GIS\data\tempdata\my_nodups.shp') #Save

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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