使用GeoPandas与Shapely合并非相交多边形(单geometry列)
问题:按农场类型合并GeoDataFrame,将多个Polygon合并为MultiPolygon
我有如下结构的GeoDataFrame(示例数据),其中Lat, Long为农场位置,分布区域存储在geometry列:
| Farm type | Lat | Long | Avg yield | Max yield | geometry |
|---|---|---|---|---|---|
| Apples | x1 | y1 | 50 | 100 | POLYGON (a) |
| Apples | x1 | y1 | 50 | 100 | POLYGON (b) |
| Apples | x1 | y1 | 50 | 100 | POLYGON (c) |
| Bananas | x2 | y2 | 100 | 150 | POLYGON (d) |
| Bananas | x2 | y2 | 100 | 150 | POLYGON (e) |
| Bananas | x2 | y2 | 100 | 150 | POLYGON (f) |
| Oranges | x3 | y3 | 70 | 100 | POLYGON (g) |
| Oranges | x3 | y3 | 70 | 100 | POLYGON (h) |
| Oranges | x3 | y3 | 70 | 100 | POLYGON (i) |
同一Farm type的其他字段值完全一致,仅geometry列的Polygon不同。我希望按Farm type合并行,得到每个类型一行的结果,将同类型的Polygon合并为MultiPolygon(多边形可能不相交,无需假设交集),期望输出如下:
| Farm type | Lat | Long | Avg yield | Max yield | geometry |
|---|---|---|---|---|---|
| Apples | x1 | y1 | 50 | 100 | MULTIPOLYGON (a,b,c) |
| Bananas | x2 | y2 | 100 | 150 | MULTIPOLYGON (d,e,f) |
| Oranges | x3 | y3 | 70 | 100 | MULTIPOLYGON (g,h,i) |
我尝试了以下代码,但未达到预期效果:
import geopandas as gpd from shapely.ops import unary_union for i in df['Farm type'].unique(): temp_poly = df.loc[df['Farm type']==i] df.loc[df['Farm type']==i, 'geometry'] = gpd.GeoSeries(unary_union(temp_poly['geometry']))
解决方案:使用groupby聚合实现合并
原代码的问题在于循环修改原DataFrame时,没有对重复行去重,且赋值过程可能存在索引匹配问题。更高效可靠的方式是用GeoPandas的groupby结合聚合函数:
import geopandas as gpd from shapely.ops import unary_union # 按Farm type分组,聚合各字段 merged_df = df.groupby('Farm type').agg( Lat=('Lat', 'first'), Long=('Long', 'first'), Avg_yield=('Avg yield', 'first'), Max_yield=('Max yield', 'first'), geometry=('geometry', unary_union) ).reset_index() # 确保结果为GeoDataFrame(若自动识别可省略) merged_df = gpd.GeoDataFrame(merged_df, geometry='geometry')
代码说明
groupby('Farm type'):按农场类型分组,自动将同类型的行归为一组。agg():对每组执行聚合操作:- 非
geometry字段用first()取值:因为同组内这些字段值完全一致,取第一个即可。 geometry字段用unary_union:将组内所有Polygon合并为单个几何对象——若多边形不相交则生成MultiPolygon,若相交则合并为单个Polygon,完美匹配需求。
- 非
reset_index():将分组的Farm type从索引转回普通列,恢复常规DataFrame结构。
这种方法避免了循环操作的索引问题,代码更简洁,处理效率也更高,尤其适合大规模数据。
内容的提问来源于stack exchange,提问作者Sprawk48
相关产品推荐
相关产品推荐

