geopandas双层循环中如何求和大面内小面统计值并存入大面新列
正确实现方案
你原有写法的问题主要集中在两点:
- 没有提前给
large_polygon初始化smth_sum字段,直接赋值会触发索引对齐异常 - 计算小面点指标时,单个小面对应多个点的场景下,直接取
df_idx['someAttribute']得到的是Series类型,直接赋值会导致smth列不是纯数值类型,无法正常求和
完整修改后代码
import geopandas as gpd small_polygon = gpd.read_file(r'R:\...\small.shp') large_polygon = gpd.read_file(r'R:\...\large.shp') points = gpd.read_file(r'R:\...\points.shp') # 提前初始化求和字段,默认值设为0避免空值问题 large_polygon['smth_sum'] = 0 SmallJoin =gpd.sjoin(small_polygon, large_polygon)[['FID', 'ID', 'someValue','geometry']] for i in large_polygon.index: df_i = SmallJoin[SmallJoin['FID'] == i] # 跳过没有关联小面的大面,减少无效计算 if df_i.empty: continue # 此处执行其他处理,例如计算小面面积 df_res = gpd.overlay(large_polygon, df_i, how='intersection') df_res['area'] = round((df_res.apply(lambda row: row.geometry.area, axis=1)), 4) # 已得到落在当前大面内的所有小面数据 df_res_2 = df_res[df_res['FID_1'] == i] # 统计小面内的点数据指标 PointsJoin =gpd.sjoin(points, df_res)[['ID','someAttribute', 'someAttribute2','geometry']] for idx, val in df_res_2['ID'].items(): df_idx = PointsJoin[PointsJoin['ID'] == val] # 单个小面内多个点时先对属性求和,保证得到单个数值 number_of_somethin = df_idx['someAttribute'].sum() + 121 + df_idx['someAttribute2'].sum() df_res_2.loc[idx, 'smth'] = number_of_somethin # 对当前大面对应的所有小面smth值求和,写入大面字段 large_polygon.loc[i, 'smth_sum'] = df_res_2['smth'].sum() # 处理完成后可以保存结果 # large_polygon.to_file(r'R:\...\large_with_sum.shp', encoding='utf-8')
原错误写法原因说明
large_polygon.loc[i, 'smth_sum'] = df_res_2['smth']:试图把一整列Series赋值给单个单元格,类型不匹配large_polygon['smth_sum'] = large_polygon[large_polygon['FID'] == df_res_2['FID_1'].sum()]:逻辑完全错误,将大面FID和小面FID的求和结果做匹配,和需求完全不符- 你写的
large_polygon.loc[i, 'smth_sum'] = df_res_2['smth'].sum()本身逻辑接近正确,只是因为前面没有初始化字段、且smth列数值计算错误才无法得到正确结果
内容的提问来源于stack exchange,提问作者g123456k
相关产品推荐
相关产品推荐

