3

I have a pandas DataFrame like this

name    loc_x    loc_y    grp_name
a1        1.0        2.0    set1
a2        2.0        3.0    set1
a3        3.2        4.1    set2
a4        7.9        4.2    set2

I want to generate a GeoDataFrame that generates a polygon using loc_x and loc_y grouped on grp_name and also includes a column name that has the values in my original data frame concatenated by |? The result should look like this

        name    geometry
set1    a1|a2   POLYGON ((1.0, 2.0)...)
set2    a3|a4   POLYGON ((3.2, 4.1)...)

I do this to get the geometry column but how do I also get an additional column with name concatenated from my base data frame?

gdf = gpd.GeoDataFrame(geometry=df.groupby('grp_name').apply(
      lambda g: Polygon(gpd.points_from_xy(g['loc_x'], g['loc_y']))))

1 Answer 1

7

Instead of using apply this can be done using the agg method with named aggregations. The only thing is that agg cannot yet operate on multiple columns, so the points must be condensed to a single column beforehand.

Also note that when converting points to polygons, the aggregation function must call .values, since x being passed there is a pd.Series, which Polygon does not know how to handle.

import pandas as pd
import geopandas as gpd
from shapely.geometry import Polygon


df = pd.DataFrame({'name':['a1','a2','a3','a4','a5','a6'],
                   'loc_x':[0,1,2,3,4,5],
                   'loc_y':[1,2,3,4,5,6],
                   'grp_name':['set1','set1','set1','set2','set2','set2']})

df['points'] = gpd.points_from_xy(df.loc_x, df.loc_y)

df = df.groupby('grp_name').agg(
     name     = pd.NamedAgg(column='name',   aggfunc = lambda x: '|'.join(x)),
     geometry = pd.NamedAgg(column='points', aggfunc = lambda x: Polygon(x.values))
    ).reset_index()

geodf = gpd.GeoDataFrame(df, geometry='geometry')

print(geodf)
  grp_name      name                                           geometry
0     set1  a1|a2|a3  POLYGON ((0.00000 1.00000, 1.00000 2.00000, 2....
1     set2  a4|a5|a6  POLYGON ((3.00000 4.00000, 4.00000 5.00000, 5....

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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