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

GeoJSON转GeoPandas DataFrame后参数丢失问题及解决方法

问题:GeoDataFrame转换与GeoJSON导出时保留parameters字段的解决方法

问题场景

现有如下DataFrame:

d = {
    'geoid': ['13085970205'],
    'FIPS': ['13085'],
    'Year': [2024],
    'parameters': [{"Year": 2024, "hpi_prediction": 304.32205}],
    'geometry':[
        {
            "coordinates": [[[[-84.126456, 34.389734], [-84.12641, 34.39026], [-84.126323, 34.39068]]]],
            "parameters": {"Year": 2024, "hpi_prediction": 304.32205},
            "type": "MultiPolygon"
        }
    ]
    
}

dd = pd.DataFrame(data=d)

执行以下GeoDataFrame转换代码时:

import geopandas as gpd
df_geopandas_hpi = gpd.GeoDataFrame(dd[['geoid', 'geometry']])

原DataFrame中的parameters字段丢失。且实际业务中需要按如下代码批量导出GeoJSON并保留parameters字段:

if ~os.path.exists('../verus_data'):
    os.mkdir('../verus_data')

for county, df_county in dd.groupby('FIPS'):
    if ~os.path.exists('../verus_data/'+str(county)):
        os.mkdir('../verus_data/'+str(county))

    if ~os.path.exists('../verus_data/'+str(county)+'/'+'predicted'):
        os.mkdir('../verus_data/'+str(county)+'/'+'predicted')

    if ~os.path.exists('../verus_data/'+str(county)+'/'+'analyzed'):
        os.mkdir('../verus_data/'+str(county)+'/'+'analyzed')    

    df_hpi = df_county[df_county['key'] == 'hpi']
    df_analyzed = df_county[df_county['key'] == 'analyzed']

    for year, df_year in df_hpi.groupby('Year'):
        if ~os.path.exists('../verus_data/'+str(county)+'/'+'predicted'+'/'+str(year)):
            os.mkdir('../verus_data/'+str(county)+'/'+'predicted'+'/'+str(year))

            df_geopandas_hpi = gpd.GeoDataFrame(df_year[['geoid', 'geometry', 'parameters']])
            df_geopandas_hpi.to_file('../verus_data/'+str(county)+'/'+'predicted'+'/'+str(year)+'/'+'hpi_predictions.geojson', driver="GeoJSON")

    for year, df_year in df_analyzed.groupby('Year'):
        if ~os.path.exists('../verus_data/'+str(county)+'/'+'analyzed'+'/'+str(year)):
            os.mkdir('../verus_data/'+str(county)+'/'+'analyzed'+'/'+str(year))

            df_geopandas_analyzed = gpd.GeoDataFrame(df_year[['geoid', 'geometry', 'parameters']])
            df_geopandas_analyzed.to_file('../verus_data/'+str(county)+'/'+'analyzed'+'/'+str(year)+'/'+'analyzed_values.geojson', driver="GeoJSON")

原因分析

  1. 直接列选取遗漏:最初的转换代码仅选取了geoid和geometry两列,未包含parameters,因此该字段直接丢失。
  2. 几何对象转换特性:你的geometry字段是geojson.geometry.MultiPolygon类型,Geopandas在将其转换为内部几何对象时,只会提取形状坐标信息,不会保留嵌套在几何对象内的parameters属性。
  3. 字典字段导出限制:即使在GeoDataFrame中保留了字典类型的parameters列,若未正确设置CRS或转换几何类型,导出GeoJSON时可能出现字段序列化异常。

解决方法

1. 保留顶层parameters列并正确导出GeoJSON

修改代码,确保转换几何类型、保留目标字段并设置坐标系:

import geopandas as gpd
import os
import pandas as pd

# 转换GeoJSON对象为Geopandas可识别的几何类型
def parse_geometry(geo_obj):
    return gpd.GeoSeries.from_features([geo_obj])[0]

# 创建根目录
if not os.path.exists('../verus_data'):
    os.mkdir('../verus_data')

# 按FIPS分组处理
for county, df_county in dd.groupby('FIPS'):
    county_dir = f'../verus_data/{county}'
    # 创建 county 目录
    if not os.path.exists(county_dir):
        os.mkdir(county_dir)
    # 创建子目录
    for sub_dir in ['predicted', 'analyzed']:
        sub_path = f'{county_dir}/{sub_dir}'
        if not os.path.exists(sub_path):
            os.mkdir(sub_path)

    # 筛选hpi和analyzed数据
    df_hpi = df_county[df_county['key'] == 'hpi']
    df_analyzed = df_county[df_county['key'] == 'analyzed']

    # 处理hpi预测数据导出
    for year, df_year in df_hpi.groupby('Year'):
        year_dir = f'{county_dir}/predicted/{year}'
        if not os.path.exists(year_dir):
            os.mkdir(year_dir)
        # 转换geometry列
        df_year['geometry'] = df_year['geometry'].apply(parse_geometry)
        # 创建GeoDataFrame,保留所需字段并设置坐标系(WGS84)
        gdf = gpd.GeoDataFrame(df_year[['geoid', 'geometry', 'parameters']], crs="EPSG:4326")
        # 导出GeoJSON
        gdf.to_file(f'{year_dir}/hpi_predictions.geojson', driver="GeoJSON")

    # 处理analyzed数据导出
    for year, df_year in df_analyzed.groupby('Year'):
        year_dir = f'{county_dir}/analyzed/{year}'
        if not os.path.exists(year_dir):
            os.mkdir(year_dir)
        df_year['geometry'] = df_year['geometry'].apply(parse_geometry)
        gdf = gpd.GeoDataFrame(df_year[['geoid', 'geometry', 'parameters']], crs="EPSG:4326")
        gdf.to_file(f'{year_dir}/analyzed_values.geojson', driver="GeoJSON")

2. 提取几何对象内部的parameters(可选)

如果需要把几何对象中嵌套的parameters也保留下来,可以添加提取逻辑:

# 提取geometry内部的parameters作为单独列
df_year['geo_parameters'] = df_year['geometry'].apply(lambda x: x.get('parameters', {}))
# 合并顶层与几何内部的parameters(可选)
df_year['combined_parameters'] = df_year.apply(lambda row: {**row['parameters'], **row['geo_parameters']}, axis=1)
# 导出时使用合并后的字段
gdf = gpd.GeoDataFrame(df_year[['geoid', 'geometry', 'combined_parameters']], crs="EPSG:4326")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 02:15:35