如何在DataFrame中展开嵌套JSON的lineups列并关联赛事数据?
解决方案
针对你遇到的DataFrame中lineups嵌套字段展开问题,这里提供两种贴合需求的处理方案:
方案1:将球员数据整理为结构化列(单赛事行保留所有球员信息)
如果希望每个赛事仍为单独一行,同时把嵌套的球员数据转化为可直接访问的结构化格式,可使用以下代码:
import pandas as pd import json # 1. 加载JSON数据并转换为初始DataFrame with open('match_data.json', 'r') as f: raw_data = json.load(f) df = pd.DataFrame([raw_data['data']]) # 2. 处理lineups中的两队球员信息,生成结构化列表 def format_lineups(lineup_dict): processed_teams = {} for team_key, players in lineup_dict.items(): processed_teams[team_key] = [ { 'player_id': p['player_id'], 'shirt_number': p['shirt_number'], 'events': p['player_events'] } for p in players ] return processed_teams # 应用处理函数,生成新的结构化列 df['formatted_lineups'] = df['lineups'].apply(format_lineups) # 可选:删除原lineups列 df = df.drop('lineups', axis=1)
处理后,formatted_lineups列会包含整理好的两队球员列表,每个球员信息以字典格式存储,既保留了嵌套数据的结构,又能在单赛事行中直接访问。
方案2:将每个球员展开为单独行(赛事数据自动关联重复)
如果需要把每个球员的信息单独成行,同时绑定对应赛事的所有数据(这是更常用的数据分析格式),可以通过json_normalize结合合并实现:
import pandas as pd import json # 1. 加载JSON数据 with open('match_data.json', 'r') as f: raw_data = json.load(f) match_info = raw_data['data'] # 2. 分别展开主队、客队的球员数据 team_a_players = pd.json_normalize(match_info['lineups']['team_a']) team_a_players['team_type'] = 'home' team_b_players = pd.json_normalize(match_info['lineups']['team_b']) team_b_players['team_type'] = 'away' # 3. 合并两队球员数据 all_players = pd.concat([team_a_players, team_b_players], ignore_index=True) # 4. 将赛事基础数据关联到每个球员行 match_base_data = {k: v for k, v in match_info.items() if k != 'lineups'} for col_name, col_value in match_base_data.items(): all_players[col_name] = col_value # 最终结果:每个球员一行,绑定对应赛事的所有字段 print(all_players.head())
这种方案下,每个球员的信息(包括player_events中的事件详情)都会单独成行,同时保留对应赛事的所有数据,方便后续做球员-赛事关联分析。
补充:进一步展开player_events的嵌套事件
如果需要把player_events中的事件也单独成行(比如每个进球、换人事件对应一行),可在方案2的基础上追加以下操作:
# 展开player_events列表 players_exploded = all_players.explode('player_events', ignore_index=True) # 展开事件中的具体字段 players_final = pd.json_normalize(players_exploded.to_dict('records')) # 处理空事件的情况(填充空字符串避免缺失值) players_final[['player_events.event_time', 'player_events.event_type']] = players_final[['player_events.event_time', 'player_events.event_type']].fillna('')
内容的提问来源于stack exchange,提问作者Tez
相关产品推荐
相关产品推荐

