【数据可视化实战】从API到图表:一步步构建奥运奖牌榜与运动员数据分析平台

张开发
2026/4/9 23:57:18 15 分钟阅读

分享文章

【数据可视化实战】从API到图表:一步步构建奥运奖牌榜与运动员数据分析平台
1. 数据获取从API到结构化数据做数据分析的第一步永远是获取数据。这次我们选择奥运奖牌榜和运动员数据作为案例主要是因为这类数据公开透明且结构清晰非常适合新手练手。我实测下来咪咕视频的奥运数据接口非常稳定返回的JSON格式也很规范。先来看看奖牌榜数据的获取方法。直接用Python的requests库就能搞定import requests rank_url https://app-sc.miguvideo.com/vms-livedata/olympic-medal/total-table/15/110000004609 data requests.get(rank_url).json()这里有个小技巧获取数据后建议立即保存原始JSON文件。我在项目里吃过亏有一次分析到一半API突然调整了数据结构导致后续代码全部报错。建议加上时间戳保存import json import time with open(fmedal_data_{int(time.time())}.json, w) as f: json.dump(data, f)运动员数据稍微复杂些需要从奥委会官网抓取。这里要注意两个细节一是国家简称和中文名称的映射关系二是运动项目的多语言转换。我整理好的代码如下# 获取国家简称映射 noc_url https://olympics.com/tokyo-2020/olympic-games/zh/results/all-sports/nocs-list.htm r requests.get(noc_url) patterns re.compile(r/li.*?country(?P简称.*?).*?div classmx-auto font-weight-bold(?P中文名称.*?)/div) noc_dict {k: v for k, v in patterns.findall(r.text)}2. 数据清洗Pandas实战技巧原始数据往往存在各种问题缺失值、格式不一致、冗余字段等。我常用的清洗流程是查看→处理→验证三步走。首先用Pandas快速查看数据概况import pandas as pd df pd.DataFrame(data[body][allMedalData]) print(df.info()) print(df.describe())奖牌数据常见的清洗需求包括处理空值比如某些国家没有银牌统一国家名称格式转换数字类型这是我优化后的清洗代码medal_df pd.DataFrame([{ 排名: item[rank], 国家: item[countryName].strip(), 金牌: int(item[goldMedalNum] or 0), 银牌: int(item[silverMedalNum] or 0), 铜牌: int(item[bronzeMedalNum] or 0), 总数: int(item[totalMedalNum]) } for item in data[body][allMedalData]])运动员数据清洗更复杂些。遇到过的一个坑是某些运动员参加了多个项目原始数据会用逗号分隔。这时候需要先做拆分athletes_df[项目] athletes_df[项目].str.split(,) athletes_df athletes_df.explode(项目)3. 数据分析挖掘有趣洞察清洗好的数据就像待雕琢的玉石需要合适的工具来展现价值。Pandas的聚合功能是我的首选武器。先看基础的奖牌分析# 按大洲分析 continent_map {中国:亚洲, 美国:美洲, ...} # 需要预先定义 medal_df[大洲] medal_df[国家].map(continent_map) continent_stats medal_df.groupby(大洲).agg({ 金牌:sum, 银牌:sum, 铜牌:sum })更高级的分析可以计算奖牌效率奖牌数/参赛人数# 合并两个数据集 analysis_df pd.merge( medal_df, athletes_df.groupby(国家).size().rename(参赛人数), left_on国家, right_indexTrue ) analysis_df[奖牌效率] analysis_df[总数] / analysis_df[参赛人数]4. 可视化呈现从静态到交互数据可视化是分析结果的最终呈现。我推荐Plotly和Pyecharts这两个库它们生成的图表既美观又交互性强。4.1 基础奖牌榜表格用Plotly创建带颜色渐变的表格import plotly.graph_objects as go fig go.Figure(data[go.Table( headerdict(valueslist(medal_df.columns)), cellsdict( valuesmedal_df.values.T, fill_color[rgb(245,245,245), rgb(220,220,220)] ) )]) fig.update_layout(title奥运奖牌榜) fig.show()4.2 交互式旭日图展示各国参赛项目分布Pyecharts的旭日图非常合适from pyecharts import options as opts from pyecharts.charts import Sunburst data [] for country, group in athletes_df.groupby(国家): children [] for sport, sub_group in group.groupby(项目): children.append({name: sport, value: len(sub_group)}) data.append({name: country, children: children}) sunburst ( Sunburst() .add(参赛情况, data, radius[0, 90%]) .set_global_opts(title_optsopts.TitleOpts(title参赛项目分布)) ) sunburst.render_notebook()4.3 动态地图展示地理数据一定要用地图展示。Pyecharts的世界地图配置from pyecharts.charts import Map world_map ( Map() .add(金牌数, list(zip(medal_df[国家], medal_df[金牌])), world) .set_series_opts(label_optsopts.LabelOpts(is_showFalse)) .set_global_opts( title_optsopts.TitleOpts(title金牌分布图), visualmap_optsopts.VisualMapOpts(max_50) ) )5. 项目优化与部署完成分析后可以考虑将项目产品化。我用Flask搭建过一个简单的数据看板from flask import Flask, render_template app Flask(__name__) app.route(/) def dashboard(): return render_template(dashboard.html, medal_tablemedal_df.to_html(), sunburstsunburst.render_embed()) if __name__ __main__: app.run()部署时遇到的典型问题包括数据更新机制定时爬取还是手动触发性能优化大数据量下的渲染速度移动端适配我的解决方案是使用APScheduler设置定时任务对静态数据预渲染HTML使用Bootstrap做响应式布局6. 避坑指南在完成这个项目的过程中我踩过不少坑这里分享几个关键经验数据缓存很重要频繁请求API可能导致IP被封建议设置合理的请求间隔或者使用本地缓存。我通常会在代码中加入这样的逻辑from pathlib import Path cache_file Path(medal_data.json) if cache_file.exists(): with open(cache_file) as f: data json.load(f) else: data requests.get(rank_url).json() with open(cache_file, w) as f: json.dump(data, f)异常处理不能少网络请求、数据解析都可能出错。完善的异常处理能让程序更健壮try: response requests.get(url, timeout10) response.raise_for_status() data response.json() except requests.exceptions.RequestException as e: print(f请求失败: {e}) # 这里可以加入重试逻辑可视化配色有讲究颜色使用不当会导致图表难以阅读。建议使用渐变色表示数值大小重要数据用对比色突出避免使用色盲人士难以区分的颜色组合性能优化技巧当处理大量数据时Pandas操作可能会变慢。几个提速方法尽量使用向量化操作而非循环对于大型DataFrame考虑使用Dask替代Pandas可视化时可以先采样再展示完整数据最后提醒一点所有体育数据都可能存在后续修正。在我的项目中就遇到过奖牌数调整的情况所以关键分析结果最好注明数据获取时间。

更多文章