You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何将嵌套JSON完整展开为Pandas DataFrame?诺贝尔奖API数据处理问题咨询

解决方案:完全展开嵌套JSON到Pandas DataFrame

我明白你想要把所有嵌套层级(包括prizes和里面的affiliations)都展开成单独列,同时保留没有获奖记录的条目。下面是一步步的实用解决方案:

方法1:一次性展开两层嵌套(推荐)

这种方法直接处理laureatesprizesaffiliations的嵌套结构,同时保留所有元数据,还能优雅处理缺失的嵌套字段:

import pandas as pd
import requests

# 拉取API数据
resp = requests.get('http://api.nobelprize.org/v1/laureate.json')
data = resp.json()

# 拆分有奖项和无奖项的获奖者,确保无奖项条目不丢失
laureates_with_prizes = [item for item in data['laureates'] if 'prizes' in item and item['prizes']]
laureates_without_prizes = [item for item in data['laureates'] if 'prizes' not in item or not item['prizes']]

# 处理有奖项的条目:一次性展开prizes和affiliations
df_with_prizes = pd.json_normalize(
    laureates_with_prizes,
    # 多层record_path指定要展开的嵌套层级
    record_path=['prizes', 'affiliations'],
    # 保留所有需要的元数据,包括获奖者信息和奖项细节
    meta=[
        'id', 'firstname', 'surname', 'born', 'died',
        'bornCountry', 'bornCountryCode', 'bornCity',
        'diedCountry', 'diedCountryCode', 'diedCity', 'gender',
        ['prizes', 'year'], ['prizes', 'category'],
        ['prizes', 'share'], ['prizes', 'motivation']
    ],
    # 忽略缺失的嵌套字段(比如没有affiliations的奖项)
    errors='ignore'
)

# 把嵌套的列名(比如('prizes', 'year'))改成更友好的格式
df_with_prizes.columns = [
    '_'.join(col) if isinstance(col, tuple) else col 
    for col in df_with_prizes.columns
]

# 处理无奖项的条目,直接转为DataFrame
df_without_prizes = pd.DataFrame(laureates_without_prizes)

# 合并两个数据集,确保所有条目都被保留
df_final = pd.concat([df_with_prizes, df_without_prizes], ignore_index=True, sort=False)

# 查看核心字段示例
print(df_final[['id', 'firstname', 'surname', 'prizes_year', 'prizes_category', 'name', 'city']].head(10))

方法2:分步展开(适合理解过程)

如果你想更清晰地看到每一步的展开逻辑,可以分两步处理:

第一步:展开prizes

# 展开获奖者的奖项,保留基础信息
df_prizes = pd.json_normalize(
    data['laureates'],
    record_path='prizes',
    meta=['id', 'firstname', 'surname', 'born', 'died', 'gender', 'bornCountry'],
    errors='ignore'
)

第二步:展开affiliations

# 展开每个奖项的附属机构,保留之前的所有列
df_final = pd.json_normalize(
    df_prizes.to_dict('records'),
    record_path='affiliations',
    meta=df_prizes.columns.drop('affiliations').tolist(),
    errors='ignore'
)

关键参数解释

  • record_path:指定要展开的嵌套列表路径,多层嵌套可以用列表形式(比如['prizes', 'affiliations'])。
  • meta:指定需要保留的非嵌套字段,包括上层的元数据(比如获奖者的姓名、ID)和嵌套层级的其他字段(比如奖项的年份、类别)。
  • errors='ignore':当某个条目没有对应的嵌套字段(比如没有prizes或者没有affiliations)时,不会抛出错误,而是生成空值或保留现有数据。

这样处理后,你就能得到一个完全扁平化的DataFrame,所有嵌套结构都被展开为单独的列,同时没有丢失任何条目。

内容的提问来源于stack exchange,提问作者Shivangi._k

火山引擎 最新活动