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

Python如何拆分API返回嵌套JSON的timeline字段实现扁平化

嵌套JSON timeline字段拆分方案

问题核心是timeline字段存储的是数组结构,直接存储整个数组不会自动把内部的键值对提升到顶级,按下面的方式修改即可:


方法1:修改现有ORM逻辑(适配你当前的代码结构)

单天数据场景(当前传last_days=1时,timeline数组只有1条记录)

直接修改to_bigquery_row方法,提取timeline数组的第一个元素,把内部字段合并到返回结果中:

def to_bigquery_row(self):
    # 取timeline中第一条统计数据
    daily_data = self.timeline[0]
    return {
        "country": self.country,
        "total": daily_data.get("total"),
        "daily": daily_data.get("daily"),
        "totalPerHundred": daily_data.get("totalPerHundred"),
        "dailyPerMillion": daily_data.get("dailyPerMillion"),
        "date": daily_data.get("date")
    }

多天数据场景(如果后续调整last_days参数拉取多日数据)

不要在to_bigquery_row里写死取第一条,修改文件写入的循环逻辑,遍历timeline数组的每一项,用字典解包直接展开字段:

with open('covidinfo.json','w') as newfile:
    response = get_country_vaccines('1')
    for item in response.json():
        data = sq_models.VaccineData.from_requests(item)
        # 遍历timeline下所有日期的统计数据,每个日期生成一行记录
        for daily_data in data.timeline:
            # 合并country字段和timeline条目内的所有字段
            row = {"country": data.country, **daily_data}
            newfile.write(json.dumps(row))
            newfile.write('\n')

这种写法不需要手动枚举timeline里的字段,后续接口新增字段也会自动同步到输出结果中。


方法2:用json_normalize直接处理接口返回(不需要ORM也能实现)

之前用json_normalize没生效是因为没有指定嵌套数组的路径,指定record_path和meta参数即可直接输出扁平化结果:

import pandas as pd

resp = get_country_vaccines('1')
# 指定timeline为要展开的数组路径,country作为保留的顶级元数据字段
flat_df = pd.json_normalize(
    resp.json(),
    record_path="timeline",
    meta=["country"]
)
# 调整列顺序匹配你需要的输出格式
flat_df = flat_df[["country", "total", "daily", "totalPerHundred", "dailyPerMillion", "date"]]
# 导出为每行一个JSON的格式,和你之前的输出文件格式一致
flat_df.to_json("covidinfo.json", orient="records", lines=True, force_ascii=False)

注意:如果timeline字段有可能返回空数组,建议在取数据前加长度判断,避免索引报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 09:54:22