You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python中关联DataFrame与SHP多边形并导出带属性的SHP

如何将DataFrame属性关联到多边形并导出带属性的Shapefile

问题说明

在Google Earth中打开Shapefile时,点击多边形会弹出属性信息。现在需要将Python DataFrame中的属性关联到对应的多边形GeoDataFrame,导出后的Shapefile也要保留这种点击显示属性的功能。

代码修正与步骤

你的代码核心问题是没有保存空间连接后的结果,另外还有几处细节需要调整:

  • 修正点DataFrame的创建方式,确保生成正确的行数据
  • 给多边形数据源CT定义明确列名,避免坐标提取错误
  • 保留空间连接后的属性数据,而非导出原始多边形
  • 适配Shapefile的字段限制(字段名长度不能超过10字符)

完整修正代码

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

# 1. 创建点数据的GeoDataFrame(修正原代码的DataFrame创建逻辑)
data = [['26-05-2022', '25-05-2024', 18, 'Acari', 'Ecorer', 40, -15.572136, -74.62736, 'Valid']]
columns = ['Approval', 'Expiring', 'Zone', 'Project', 'Owner', 'Size(MW)', 'Latitude', 'Longitude', 'Status']
df = pd.DataFrame(data=data, columns=columns)
geom = [Point(xy) for xy in zip(df['Latitude'], df['Longitude'])]
gdf = gpd.GeoDataFrame(df, crs='epsg:4326', geometry=geom)

# 2. 创建多边形DataFrame并生成多边形几何
# 给CT数据定义列名
ct_columns = ['ID', 'X', 'Y', 'Approval', 'Expiring', 'Zone', 'Project', 'Owner', 'Size(MW)', 'Latitude', 'Longitude', 'Status']
CT = pd.DataFrame([
    ['A', 539953.3394,  8278356.7631,  '04-01-2022',  '04-01-2024',  18,  'Acari',  'ECORER',  40.0,  -15.572135812938946,  -74.62735981024672,  'Valid'],
    ['B',  543394.3582,  8278598.5842,  '04-01-2022',  '04-01-2024',  18,  'Acari',  'ECORER',  40.0,  -15.569892965187252,  -74.59527065391799,  'Valid'],
    ['C',  544374.9396,  8275284.2101,  '04-01-2022',  '04-01-2024',  18,  'Acari',  'ECORER',  40.0,  -15.599839630766777,  -74.58606516268479,  'Valid'],
    ['D',  545165.1468,  8272748.721,  '04-01-2022',  '04-01-2024',  18,  'Acari',  'ECORER',  40.0,  -15.622747690023045,  -74.57864734907821,  'Valid'],
    ['E',  544788.7396,  8271839.3717,  '04-01-2022',  '04-01-2024',  18,  'Acari',  'ECORER',  40.0,  -15.63097535601474,  -74.58214217679688,  'Valid'],
    ['F',  544531.8483,  8271218.7568,  '04-01-2022',  '04-01-2024',  18,  'Acari',  'ECORER',  40.0,  -15.636590561754735,  -74.58452749145272,  'Valid'],
    ['G',  544456.7666,  8271027.6721,  '04-01-2022',  '04-01-2024',  18, 'Acari',  'ECORER',  40.0,  -15.638319383853226,  -74.58522449548815,  'Valid'],
    ['H',  542762.6508,  8271564.0591,  '04-01-2022',  '04-01-2024',  18,  'Acari',  'ECORER',  40.0,  -15.6334994985371,  -74.60103947340889,  'Valid'],
    ['I',  539422.042,  8272621.7549,  '04-01-2022',  '04-01-2024',  18, 'Acari',  'ECORER',  40.0,  -15.623991822179361,  -74.63222276450333, 'Valid'],
    ['J',  539213.6429,  8272687.7377,  '04-01-2022',  '04-01-2024',  18,  'Acari',  'ECORER',  40.0,  -15.62339855055848,  -74.63416799727298, 'Valid'],
    ['K',  539093.1442,  8272725.8897,  '04-01-2022',  '04-01-2024',  18,  'Acari',  'ECORER',  40.0,  -15.623055506219488,  -74.63529274775954, 'Valid'],
    ['L',  538990.1647,  8272773.0558,  '04-01-2022',  '04-01-2024',  18, 'Acari',  'ECORER',  40.0,  -15.622630692945311,  -74.63625420113516, 'Valid'],
    ['M',  538932.8284,  8272868.6162,  '04-01-2022',  '04-01-2024',  18, 'Acari',  'ECORER',  40.0,  -15.621767660560035,  -74.63679061525991, 'Valid'],
    ['N',  538985.7452,  8273196.7002,  '04-01-2022',  '04-01-2024',  18, 'Acari',  'ECORER',  40.0,  -15.618800785309029,  -74.63630218613136, 'Valid'],
    ['O',  538687.323,  8273598.3445,  '04-01-2022',  '04-01-2024',  18,  'Acari',  'ECORER',  40.0,  -15.61517429311052,  -74.63909247921848, 'Valid'],
    ['P',  538678.0626,  8274064.0121,  '04-01-2022',  '04-01-2024',  18,  'Acari',  'ECORER',  40.0,  -15.610964542228787,  -74.63918622946272, 'Valid'],
    ['Q',  538924.4467,  8274264.8223,  '04-01-2022',  '04-01-2024',  18,  'Acari',  'ECORER',  40.0,  -15.609145320024819,  -74.63689102823527, 'Valid'],
    ['R',  538947.8091,  8275898.3227,  '04-01-2022',  '04-01-2024',  18,  'Acari',  'ECORER',  40.0,  -15.594377201030477,  -74.63669908037944,'Valid']
], columns=ct_columns)

# 生成多边形几何
CTP = CT[['Latitude', 'Longitude']]
polygon_geom = Polygon(zip(CTP['Longitude'], CTP['Latitude']))
polygon = gpd.GeoDataFrame(index=[0], crs='epsg:4326', geometry=[polygon_geom])

# 3. 空间连接:将点的属性关联到多边形(仅关联多边形内部的点)
polygonExport = polygon.sjoin(gdf, how='left', predicate='contains')

# 4. 适配Shapefile字段限制:缩短超长列名
polygonExport.rename(columns={
    'Size(MW)': 'SizeMW'
}, inplace=True)

# 5. 导出带属性的Shapefile
url = "./"  # 替换为你的实际保存路径
projectName = "my_polygon"
polygonExport.to_file(filename=f"{url}{projectName}.shp", driver="ESRI Shapefile")

关键说明

  • 空间连接逻辑:使用predicate='contains'确保只有落在多边形内部的点属性会被关联
  • 字段名适配:Shapefile对字段名长度有限制,超过10字符的列名必须缩短,否则导出时会被自动截断导致属性丢失
  • 结果保存:必须导出polygonExport而非原始的polygon,才能保留关联后的属性数据

内容的提问来源于stack exchange,提问作者Maria Fernanda

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 13:57:33