使用json_normalize处理API嵌套数据,无法生成指定结构DataFrame
足球赛事统计数据格式转换问题
调用足球赛事统计API获取数据后,提取response字段下的球队信息及统计列表集合,用pd.json_normalize(fixture_ids, record_path='statistics', meta=[['team','id']])处理后得到的是统计类型、对应值与球队ID分行展示的结果,但需要将统计类型(如Shots on Goal)作为列名,每个球队一行展示所有统计值。
调用API代码
url = "https://api-football-v1.p.rapidapi.com/v3/fixtures/statistics" querystring = {"fixture":"1220142"} headers = { "x-rapidapi-key": "MY_KEY", "x-rapidapi-host": "api-football-v1.p.rapidapi.com" } response = requests.get(url, headers=headers, params=querystring) fixture_ids = response.json()['response'] # 需提取response字段,原代码补充此步骤
原始数据(response字段内容)
[{'team': {'id': 250, 'name': 'Kilmarnock', 'logo': 'https://media.api-sports.io/football/teams/250.png'}, 'statistics': [{'type': 'Shots on Goal', 'value': 3}, {'type': 'Shots off Goal', 'value': 7}]}, {'team': {'id': 1386, 'name': 'Dundee Utd', 'logo': 'https://media.api-sports.io/football/teams/1386.png'}, 'statistics': [{'type': 'Shots on Goal', 'value': 8}, {'type': 'Shots off Goal', 'value': 4}]}]
当前输出
| type | value | team.id |
|---|---|---|
| Shots on Goal | 3 | 250 |
| Shots off Goal | 7 | 250 |
| ... | ... | ... |
| Shots on Goal | 8 | 1386 |
期望输出
| Team ID | Shots on Goal | Shots off Goal |
|---|---|---|
| 250 | 3 | 7 |
| 1386 | 8 | 4 |
解决方案
用**透视表(pivot)**即可实现格式转换,步骤如下:
- 先解析原始数据(确保提取
response字段):
import pandas as pd import requests # 调用API并提取response数据 url = "https://api-football-v1.p.rapidapi.com/v3/fixtures/statistics" querystring = {"fixture":"1220142"} headers = { "x-rapidapi-key": "MY_KEY", "x-rapidapi-host": "api-football-v1.p.rapidapi.com" } response = requests.get(url, headers=headers, params=querystring) fixture_data = response.json()['response'] # 解析为基础DataFrame df = pd.json_normalize(fixture_data, record_path='statistics', meta=[['team','id']])
- 执行透视转换并调整格式:
# 将统计类型转为列,球队ID作为行 pivoted_df = df.pivot(index='team.id', columns='type', values='value').reset_index() # 重命名列并清理层级 pivoted_df.rename(columns={'team.id': 'Team ID'}, inplace=True) pivoted_df.columns.name = None
此时pivoted_df的格式就和期望输出完全一致。如果存在同一球队同一统计类型多值的情况,改用pivot_table指定聚合函数即可:
# 用first取第一个值,也可根据需求用sum/mean等 pivoted_df = df.pivot_table(index='team.id', columns='type', values='value', aggfunc='first').reset_index()
内容的提问来源于stack exchange,提问作者David27
相关产品推荐
相关产品推荐

