Renaming geometry column in GeoDataFrame with more than one geometry

Viewed 4720

I have this issue with dataframes with more than one column of type geometry. My dataframe looks like this:

New_zone_short_edges = 

       id  vertex_id                    point1  \
1   A1                2  POINT (119.79008 28.35047)   
3   A1                4  POINT (122.85067 44.85106)   
5   A2                1  POINT (138.79141 26.48802)   
7   A2                3  POINT (141.73386 44.89716)   
13   A3               5   POINT (68.47770 44.07370)   
11   A3               3   POINT (46.63571 51.16575)   

                      point2    length                    midpoint  
1   POINT (122.85067 28.08433)    3.072140  POINT (121.32038 28.21740)  
3   POINT (119.92314 44.71798)    2.930553  POINT (121.38690 44.78452)  
5   POINT (141.92247 26.26168)    3.139230  POINT (140.35694 26.37485)  
7   POINT (138.79141 44.89716)    2.942450  POINT (140.26263 44.89716)  
13   POINT (65.42208 48.14785)    5.092692   POINT (66.94989 46.11078)  
11   POINT (46.59798 47.65744)    3.508504   POINT (46.61685 49.41159) 

with the following info:

<class 'geopandas.geodataframe.GeoDataFrame'>
Int64Index: 206 entries, 1 to 425
Data columns (total 6 columns):
 #   Column      Non-Null Count  Dtype   
---  ------      --------------  -----   
 0   id          206 non-null    object  
 1   vertex_id   206 non-null    int64   
 2     point1    206 non-null    geometry
 3     point2    206 non-null    geometry
 4     length    206 non-null    float64 
 5   midpoint    206 non-null    geometry
dtypes: float64(1), geometry(3), int64(1), object(1)
memory usage: 11.3+ KB
None

Now, if my dataframe were a pandas dataframe, I could rename an individual column using for instance:

New_zone_short_edges = New_zone_short_edges.rename(columns ={'point1':'new_point'})

But since I wish to rename a geometry, I need to do something like this:

New_zone_short_edges.rename_geometry('<the new name>', inplace=True)

This is problematic since I cannot choose which geometry to rename. Is there something similar to do as with pandas?

Splitting my dataframe in three, changing the geometry name and then merging with the other seems like a tedious thing to do if it can be avoided. I have looked everywhere for an alternative without any luck. I have read somewhere that it is bad practice to have several geometries in a single dataset, but for my purposes it is, at least for calculations, imperative to have it this way.

Any idea is welcome. Thanks!

1 Answers

Renaming works fine as your first try:

>>> df.rename(columns ={'point1':'new_point'})
    id  vertex_id                   new_point                      point2    length                    midpoint
1   A1          2  POINT (119.79008 28.35047)  POINT (122.85067 28.08433)  3.072140  POINT (121.32038 28.21740)
3   A1          4  POINT (122.85067 44.85106)  POINT (119.92314 44.71798)  2.930553  POINT (121.38690 44.78452)
5   A2          1  POINT (138.79141 26.48802)  POINT (141.92247 26.26168)  3.139230  POINT (140.35694 26.37485)
7   A2          3  POINT (141.73386 44.89716)  POINT (138.79141 44.89716)  2.942450  POINT (140.26263 44.89716)
13  A3          5   POINT (68.47770 44.07370)   POINT (65.42208 48.14785)  5.092692   POINT (66.94989 46.11078)
11  A3          3   POINT (46.63571 51.16575)   POINT (46.59798 47.65744)  3.508504   POINT (46.61685 49.41159)
>>> df.rename(columns ={'point1':'new_point'}).info()
<class 'geopandas.geodataframe.GeoDataFrame'>
Int64Index: 6 entries, 1 to 11
Data columns (total 6 columns):
 #   Column     Non-Null Count  Dtype   
---  ------     --------------  -----   
 0   id         6 non-null      object  
 1   vertex_id  6 non-null      int64   
 2   new_point  6 non-null      geometry
 3   point2     6 non-null      geometry
 4   length     6 non-null      float64 
 5   midpoint   6 non-null      geometry
dtypes: float64(1), geometry(3), int64(1), object(1)
memory usage: 508.0+ bytes

It seems you might be confused by the fact that rename_geometry does not require you to specify which geometry column to rename − that’s because it sets the active geometry column.

A GeoDataFrame may also contain other columns with geometrical (shapely) objects, but only one column can be the active geometry at a time. To change which column is the active geometry column, use the GeoDataFrame.set_geometry() method.

It’s basically the column that is returned by the df.geometry accessor, and the column you passed as geometry= argument to the GeoDataFrame constructor.

For example setting the point1 column that way:

>>> df.set_geometry('point1').rename_geometry('new point').info()
<class 'geopandas.geodataframe.GeoDataFrame'>
Int64Index: 6 entries, 1 to 11
Data columns (total 6 columns):
 #   Column     Non-Null Count  Dtype   
---  ------     --------------  -----   
 0   id         6 non-null      object  
 1   vertex_id  6 non-null      int64   
 2   new point  6 non-null      geometry
 3   point2     6 non-null      geometry
 4   length     6 non-null      float64 
 5   midpoint   6 non-null      geometry
dtypes: float64(1), geometry(3), int64(1), object(1)
memory usage: 508.0+ bytes

This is useful for plotting with GeoDataFrame.plot for example. The arguments you specify decide the plotting color, and the shape(s) are decided by the geometry column.

The issue you run into if you rename without rename_geometry is that your GeoDataFrame then loses track of its active geometry column:

>>> df.set_geometry('point1').rename(columns={'point1': 'new point'}).plot()
[...]
AttributeError: No geometry data set yet (expected in column 'point1'.)

So you need to either

  • rename your active geometry column with .rename_geometry() and other columns with .rename()
  • rename all columns with .rename() and then set the active geometry again with .set_geometry(new_column_name)
Related