遍历嵌套层级后合并pandas dataframe 格式化API数据导入PostgreSQL
问题根因
你当前代码错误使用了append方法实现字段合并:append是行追加操作,而非将上层公共字段(season/week/poll等)合并到子排名记录的同一行中,所以会出现每行仅单个字段有值的问题,同时多层循环手写拆包效率极低,且容易漏数据。
最优实现方案
直接使用pandas内置的json_normalize工具处理嵌套JSON结构,无需手动循环拆包,代码简洁且效率更高,完整实现如下:
import pandas as pd import requests from tqdm import tqdm # 配置参数 years = range(2020, 2024) # 按需调整年份范围 headers = { "Accept": "application/json", "Authorization": "Bearer 1a2b3c4d" } df_list = [] for year in tqdm(years, desc='拉取排名数据'): params = {"year": year, "seasonType": "regular"} resp = requests.get("https://api.collegefootballdata.com/rankings", headers=headers, params=params) resp.raise_for_status() # 接口报错直接抛出异常 raw_data = resp.json() # 嵌套JSON扁平化 year_df = pd.json_normalize( raw_data, record_path=['polls', 'ranks'], # 最内层要展开的排名数组路径 meta=[ 'season', # 赛季 'seasonType', # 赛季类型 'week', # 周次 ['polls', 'poll'] # 所属投票榜单名称 ] ) df_list.append(year_df) # 合并所有年份数据 final_df = pd.concat(df_list, ignore_index=True)
结果说明
得到的final_df就是完全扁平的结构化表,每条排名记录自带完整的赛季、周次、榜单名称、排名、学校、联盟、得票、积分等所有字段,无空值,可直接导入PostgreSQL数据库。
如果你确实只需要每个polls数组的第二个投票榜单,在调用json_normalize前先对raw_data做过滤即可:
for item in raw_data: item['polls'] = [item['polls'][1]] if len(item['polls'])>=2 else []
内容的提问来源于stack exchange,提问作者mayord
相关产品推荐
相关产品推荐

