In Modify pandas DataFrame within iterrows loop
The rows you get back from iterrows are copies that are no longer connected to the original data frame, so edits don't change your DataFrame
. However, you can use the index to access and edit the relevant row of the DataFrame
. (for bud_row['vertex_counter'] += n
)
Therefore you can assign values in the loop using pandas .at
(or pandas .loc
):
import geopandas as gpd
gdf = gpd.read_file("polygons.shp")
gdf['vertex_counter'] = 0
for index, row in gdf.iterrows():
gdf.at[index,'vertex_counter'] = len(row['geometry'].exterior.coords
# or gdf.loc[index,'vertex_counter'] = len(row['geometry'].exterior.coords
print(gdf)
name geometry vertex_counter
0 uno POLYGON ((-0.59330 0.68268, -0.55084 0.32737, ... 8
1 dos POLYGON ((0.01229 -0.30726, 0.05922 -0.21117, ... 8
2 tres POLYGON ((0.34749 0.57318, 0.80559 0.60894, 0.... 5
But if you look at How to iterate over rows in a DataFrame in Pandas or pandas.DataFrame.iterrows ("You should never modify something you are iterating over") it is preferable to use
The apply function
import geopandas as gpd
gdf = gpd.read_file("polygons.shp")
gdf['vertex_counter'] = gdf.apply(lambda row: len(row.geometry.exterior.coords),axis=1)
print(gdf)
name geometry vertex_counter
0 uno POLYGON ((-0.59330 0.68268, -0.55084 0.32737, ... 8
1 dos POLYGON ((0.01229 -0.30726, 0.05922 -0.21117, ... 8
2 tres POLYGON ((0.34749 0.57318, 0.80559 0.60894, 0.... 5
The List Comprehensions method
gdf = gpd.read_file("polygons.shp")
n = [len(geom.exterior.coords) for geom in gdf.geometry]
gdf['vertex_counter'] = n
print(gdf)
name geometry vertex_counter
0 uno POLYGON ((-0.59330 0.68268, -0.55084 0.32737, ... 8
1 dos POLYGON ((0.01229 -0.30726, 0.05922 -0.21117, ... 8
2 tres POLYGON ((0.34749 0.57318, 0.80559 0.60894, 0.... 5
With itertuples()
and List Comprehensions:
gdf['vertex_counter'] = [len(i.geometry.exterior.coords) for i in gdf.itertuples()]
With iterrows()
and List Comprehensions:
gdf['vertex_counter1'] = [len(row['geometry'].exterior.coords) for index, row in gdf.iterrows()]
Eventually, you can also create a new empty GeoDataFrame
and populate it:
gdf = gpd.read_file("polygons.shp")
gdf['vertex_counter'] = 0
new = gpd.GeoDataFrame(columns=gdf.columns)
for index, row in gdf.iterrows():
row['vertex_counter'] = len(row['geometry'].exterior.coords)
new = new.append(row)