Python中JSON转DataFrame/GeoDataFrame缺失字段如何处理?
问题:提取JSON嵌套字段并处理缺失值
读取JSON文件到DataFrame后,features列包含嵌套的Feature结构,部分属性字段(如levels、orient)并非所有行都存在,直接提取会触发KeyError,需要提取所有字段并将缺失值设为null。
原始数据读取示例:
import pandas as pd PT = pd.read_json('PT.json') # PT结构: # type features # 0 FeatureCollection {'id': 'osm-w96717521', 'type': 'Feature', ...} # 1 FeatureCollection {'id': 'osm-w96850552', 'type': 'Feature', ...}
单个Feature的嵌套结构示例:
PT['features'][0] # 输出: # {'id': 'osm-w96717521', # 'type': 'Feature', # 'properties': {'height': 24, 'heightSrc': 'manual', 'levels': 8, 'date': 201804}, # 'geometry': {'type': 'Polygon', 'coordinates': [[[-9.151539, 38.725054], ...]]}}
直接提取非全量字段时的错误:
df["floors"] = PT["features"].apply(lambda row: row["properties"]["levels"]) # 触发报错:KeyError: 'levels'
解决方案1:使用字典get()方法提取单个字段
利用字典的get()方法,指定缺失时返回NaN(需导入numpy),避免KeyError:
import numpy as np # 提取levels字段,缺失值设为NaN df["floors"] = PT["features"].apply(lambda row: row["properties"].get("levels", np.nan)) # 提取orient字段,缺失值设为NaN df["orient"] = PT["features"].apply(lambda row: row["properties"].get("orient", np.nan)) # 提取geometry坐标(全量存在的字段可直接索引) df["coordinates"] = PT["features"].apply(lambda row: row["geometry"]["coordinates"])
解决方案2:用pd.json_normalize()一次性展开所有嵌套字段
此方法可自动展开features中的所有嵌套结构,包括properties下的所有字段,缺失值自动填充为NaN,适合批量处理:
# 展开features列的所有嵌套字段 df_normalized = pd.json_normalize(PT['features']) # 可选:简化列名(移除properties.、geometry.前缀) df_normalized = df_normalized.rename(columns=lambda x: x.replace('properties.', '').replace('geometry.', ''))
解决方案3:直接转换为GeoDataFrame
如果目标是生成GeoDataFrame,推荐用geopandas直接处理,无需手动拆分字段:
import geopandas as gpd from shapely.geometry import shape # 方法1:直接读取GeoJSON文件(若JSON为标准GeoJSON格式) gdf = gpd.read_file('PT.json') # 方法2:基于已读取的PT DataFrame转换 # 先展开嵌套字段,再解析geometry df_normalized = pd.json_normalize(PT['features']) gdf = gpd.GeoDataFrame( df_normalized.drop(columns=['geometry']), geometry=[shape(row['geometry']) for row in PT['features']] )
内容的提问来源于stack exchange,提问作者Ricardo Gomes
相关产品推荐
相关产品推荐

