使用pandas.json_normalize转换嵌套JSON为指定结构DataFrame
问题根因
你当前使用pd.json_normalize的参数配置和接口返回的JSON嵌套层级完全不匹配:
data['campsites']是以营地唯一ID为键的嵌套字典,并非列表结构,直接传入json_normalize会导致函数无法定位内部嵌套字段的路径record_path='availabilities'的配置不符合数据结构:该字段是嵌在每个营地条目内部的键值对字典(格式为{日期字符串: 可用状态}),本身不是可直接展开的列表结构meta='campsites'的路径完全错误,meta参数用于指定需要从父层级保留的字段路径,并非整个数据块的标识
可直接运行的实现代码
import json import urllib.request import pandas as pd url = "https://www.recreation.gov/api/camps/availability/campground/232447/month?start_date=2021-05-01T00%3A00%3A00.000Z" with urllib.request.urlopen(url) as resp: data = json.loads(resp.read().decode()) # 1. 以营地ID为索引,生成营地基础信息表 campsite_base = pd.DataFrame.from_dict(data['campsites'], orient='index') # 2. 展开availabilities嵌套字典,生成(营地ID, 日期, 状态)长表 avail_long = ( campsite_base['availabilities'] .apply(pd.Series) # 将每个营地的{日期:状态}字典拆为宽表列 .stack() # 宽表转长表,生成(原营地ID, 日期)的双层索引 .reset_index(name='availability_status') .rename(columns={'level_0': 'parent_campsite_id'}) ) # 3. 关联营地基础信息,生成最终结构化DataFrame final_df = avail_long.merge( campsite_base.drop(columns=['availabilities']), left_on='parent_campsite_id', right_index=True, how='left' ) # 过滤空状态行,按需调整列顺序匹配参考结构 final_df = final_df.dropna(subset=['availability_status']) print(final_df.head())
优化提示:如果需要将日期列格式化为纯日期字符串,只需对日期列做简单截取:
final_df['date'] = final_df['level_1'].str.slice(0, 10)
最终输出的列会包含营地ID、站点编号、站点类型、日期、可用状态,和参考截图的结构完全一致。
内容的提问来源于stack exchange,提问作者PythonRookie
相关产品推荐
相关产品推荐

