Python 奥运会数据分析完整实战(pandas+pyecharts+matplotlib)附源码 + 可视化
文章简介
大家好,今天分享一套完整奥运会运动员数据集数据分析实战项目,基于athlete_events.csv、noc_regions.csv两份官方奥运数据,使用pandas做数据清洗、统计分析,搭配matplotlib绘制基础图表、pyecharts制作交互式可视化。 全文覆盖数据加载融合、缺失值清洗、运动员特征分析、全球各国奖牌对比、中国奥运专项深度挖掘四大模块,完整可运行,适合数据分析课程作业、毕设、CSDN 练手项目。
一、项目环境与依赖安装
1. 所需库
- pandas:数据处理、表格合并、分组统计
- numpy:数值计算
- matplotlib:静态可视化(饼图、折线、柱状、箱线图)
- pyecharts:交互式图表(柱状图、玫瑰饼图)
- warnings:屏蔽运行警告
2. 安装命令
python
运行
! pip install pyecharts pandas numpy matplotlib
3. 全局配置(解决中文、负号乱码)
python
运行
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# 设置中文显示
plt.rcParams['font.sans-serif'] = ['SimHei']
# 设置负号正常显示
plt.rcParams['axes.unicode_minus'] = False
from pyecharts.charts import *
from pyecharts import options as opts
# 屏蔽警告
import warnings
warnings.filterwarnings('ignore')
二、阶段一:数据加载、多表融合与基础探查
1. 读取两份数据集
数据集说明:
athlete_events.csv:每条记录代表一名运动员单届奥运参赛记录,包含年龄、身高、体重、项目、奖牌、年份、性别等核心字段noc_regions.csv:NOC 国家代码与国家全称映射表,用于匹配国家名称
python
运行
# 加载数据
df_athletes = pd.read_csv('athlete_events.csv')
df_regions = pd.read_csv('noc_regions.csv')
# 查看前两行数据
print(df_athletes.head(2))
2. 左连接合并两张表
使用左连接保证所有运动员数据不丢失,匹配对应国家名称 region
python
运行
# 左连接,关联NOC国家编码
df = pd.merge(df_athletes, df_regions, on='NOC', how='left')
print(df.head())
3. 基础数据信息探查
(1)查看数据行列、缺失值、字段类型
python
运行
df.info()
数据集共 271116 条记录,17 个字段:
- 数值型:ID、Year、Age、Height、Weight(年龄、身高、体重存在大量缺失)
- 字符串型:姓名、性别、国家、赛事、项目、奖牌、地区等
- Medal 奖牌字段缺失极多(大部分运动员无奖牌)
(2)查看缺失 NOC 国家编码
python
运行
# region为空的国家编码
missing_NOC=df[df['region'].isna()]['NOC'].unique()
print("缺失地区映射的NOC编码:", missing_NOC)
输出:['SGP', 'ROT', 'UNK', 'TUV'],多为难民、临时独立组织,不影响主体分析。
(3)数值字段描述性统计
python
运行
print(df.describe())
关键指标解读:
- 运动员平均年龄 25.56 岁,最小 10 岁,最大 97 岁
- 平均身高 175.34cm,平均体重 70.7kg
- 赛事年份跨度 1896-2016,覆盖百年奥运历史
三、阶段二:数据清洗与特征工程(核心预处理)
原始数据存在大量缺失值,需要统一填充,同时可衍生 BMI 身体质量指数特征。
1. 缺失值填充策略
- region(国家)缺失填充
Unknown - Medal 奖牌空值填充
No Medal(区分金银铜无奖牌) - Age 年龄:均值填充
- Height 身高:中位数填充(避免极端身高干扰)
- Weight 体重:均值填充
python
运行
# 国家缺失填充
df['region']=df['region'].fillna('Unknown')
# 奖牌缺失填充无奖牌
df['Medal']=df['Medal'].fillna('No Medal')
# 年龄、身高、体重填充
df['Age']=df['Age'].fillna(df['Age'].mean())
df['Height']=df['Height'].fillna(df['Height'].median())
df['Weight']=df['Weight'].fillna(df['Weight'].mean())
# 清洗后再次查看缺失
df.info()
2. 历史国家统一映射说明
数据中存在历史政权拆分 / 合并,统一归类方便统计:
- Russia:苏联 URS、独联体 EUN、俄罗斯 RUS 统一归为 Russia
- Germany:西德 FRG、东德 GDR、统一德国 GER 全部归为 Germany
python
运行
# 查看俄罗斯相关NOC
print(df[df['region']=='Russia']['NOC'].unique())
# 查看德国相关NOC
print(df[df['region']=='Germany']['NOC'].unique())
3. 衍生 BMI 特征(修复原文报错 KeyError)
原文代码报错是因为未提前创建 BMI 列,修复后完整代码:
python
运行
# 新增BMI字段:体重(kg) / 身高(m)平方
df['BMI'] = df['Weight'] / ((df['Height']/100) ** 2)
4. 重复值检测
python
运行
# 根据姓名+年龄判断重复参赛记录
dup_count = df.duplicated(subset=['Name','Age']).sum()
print(f"姓名+年龄重复记录数:{dup_count}")
共 84156 条重复参赛记录,本次分析不做删除,保留全部参赛数据。
四、阶段三:全球奥运宏观探索性分析
1. 运动员基础特征可视化
(1)男女运动员性别分布饼图
python
运行
plt.figure(figsize=(8,8))
df['Sex'].value_counts().plot.pie(autopct='%1.1f%%',shadow=True,explode=(0.1,0))
plt.title('奥运会男女运动员性别分布')
plt.ylabel("")
plt.show()
结论:历史奥运男性运动员占比 72.5%,女性仅 27.5%,早期奥运女性参赛限制严重。
(2)男女运动员年龄箱线图
python
运行
df.boxplot(column='Age',by='Sex',figsize=(10,6))
plt.title("男女运动员年龄分布箱线图")
plt.suptitle("") # 去除自动标题
plt.xlabel("性别")
plt.ylabel("年龄")
plt.show()
结论:男女运动员年龄中位数均在 24 岁左右,男性年龄离散度更大,高龄参赛选手更多。
(3)男女 BMI 分布直方图
python
运行
plt.figure(figsize=(16,6))
plt.hist(df[df['Sex']=='M']['BMI'],bins=30,alpha=0.5,label='男性')
plt.hist(df[df['Sex']=='F']['BMI'],bins=30,alpha=0.5,label='女性')
plt.xlabel('BMI指数')
plt.ylabel('人数')
plt.legend()
plt.title('男女运动员BMI分布直方图')
plt.show()
2. 百年奥运男女平均年龄变化趋势
python
运行
plt.figure(figsize=(16,6))
# 男性每年平均年龄
df[df['Sex']=='M'].groupby('Year')['Age'].mean().plot(marker='o')
# 女性每年平均年龄
df[df['Sex']=='F'].groupby('Year')['Age'].mean().plot(marker='*')
plt.title('1896-2016男女参赛选手平均年龄变化')
plt.xlabel('年份')
plt.ylabel('平均年龄')
plt.legend(['男性','女性'])
plt.grid(alpha=0.3)
plt.show()
3. 全球各国奖牌数据分析
(1)1994 年后各国总奖牌 Top20(现代奥运格局)
python
运行
# 筛选有奖牌记录
df_medal=df[df['Medal']!='No Medal']
# 1994苏联解体后现代奥运
df_medal = df_medal[df_medal['Year']>=1994]
# 按国家统计奖牌数量,降序取前20
data = df_medal.groupby('region')['Medal'].count().sort_values(ascending=False).head(20)
# 水平柱状图
data.plot(kind='barh',figsize=(16,6))
plt.title('1994年后全球奖牌榜Top20国家')
plt.xlabel('奖牌总数')
plt.ylabel('国家')
plt.show()
结论:美国、俄罗斯、中国稳居奖牌榜前三,传统欧洲体育强国英法德意紧随其后。
(2)奖牌最多的十大运动项目
python
运行
df_medal=df[df['Medal']!='No Medal']
sport_medal = df_medal.groupby('Sport')['Medal'].count().sort_values(ascending=False).head(10)
sport_medal.plot(kind='barh',figsize=(16,6))
plt.title('奖牌数量最多的10大奥运项目')
plt.xlabel('奖牌数')
plt.ylabel('运动项目')
plt.show()
田径、游泳、体操为传统金牌大户。
(3)中美俄德英五大强国优势项目对比(pyecharts 交互式柱状图)
python
运行
# 仅筛选金牌
df_gold=df[df['Medal']=='Gold']
# 各国金牌项目Top8
df_USA=df_gold[df_gold['region']=='USA'].groupby('Sport')['Medal'].count().head(8)
df_UK=df_gold[df_gold['region']=='UK'].groupby('Sport')['Medal'].count().head(8)
df_China=df_gold[df_gold['region']=='China'].groupby('Sport')['Medal'].count().head(8)
df_Germany=df_gold[df_gold['region']=='Germany'].groupby('Sport')['Medal'].count().head(8)
df_Russia=df_gold[df_gold['region']=='Russia'].groupby('Sport')['Medal'].count().head(8)
# pyecharts柱状图
bar=(
Bar(init_opts=opts.InitOpts(width='1000px',height='500px'))
.add_xaxis(df_USA.index.astype(str).tolist())
.add_yaxis('美国',df_USA.tolist())
.add_yaxis('英国',df_UK.tolist())
.add_yaxis('中国',df_China.tolist())
.add_yaxis('德国',df_Germany.tolist())
.add_yaxis('俄罗斯',df_Russia.tolist())
.set_global_opts(title_opts=opts.TitleOpts(title='中美俄德英五大体育强国优势金牌项目'))
)
bar.render_notebook()
# bar.render("各国优势项目.html") # 导出html文件
(4)仅获得≤3 枚奖牌的小众国家
python
运行
df_medal=df[df['Medal']!='No Medal']
less_medal_country=df_medal.groupby('region')['Medal'].count()
less_medal_country=less_medal_country[less_medal_country<=3].sort_values(ascending=False)
less_medal_country.plot(kind='barh',figsize=(14,8),title='历史仅获得3枚及以下奖牌的国家/地区')
plt.show()
五、阶段四:聚焦中国 —— 奥运崛起专项分析
1. 提取中国全部参赛数据
python
运行
# 筛选中国选手
df_china=df[df['region']=='China']
# 筛选获奖选手
df_china_medal=df_china[df_china['Medal']!='No Medal']
2. 中国夏 / 冬奥奖牌历年变化折线图
python
运行
# 夏季奥运奖牌统计
df_summer=df_china_medal[df_china_medal['Season']=='Summer'].groupby('Year')['Medal'].count()
# 冬季奥运奖牌统计
df_winter=df_china_medal[df_china_medal['Season']=='Winter'].groupby('Year')['Medal'].count()
plt.figure(figsize=(12,6))
df_summer.plot(kind='line',marker='o',label='夏季奥运会')
df_winter.plot(kind='line',marker='*',label='冬季奥运会')
plt.title('中国历年夏、冬季奥运会奖牌数量变化')
plt.xlabel('年份')
plt.ylabel('奖牌总数')
plt.legend()
plt.grid(alpha=0.2)
plt.show()
结论:夏季奥运奖牌持续稳步上涨,冬季奥运 2010 年后快速突破。
3. 中国奥运首金溯源
python
运行
# 获得金牌最小年份
first_gold_year=df_china_medal[df_china_medal['Medal']=='Gold']['Year'].min()
print(f"中国奥运首金年份:{first_gold_year}")
# 1984洛杉矶首金全部选手
first_gold_data = df_china_medal[(df_china_medal['Year']==first_gold_year) & (df_china_medal['Medal']=='Gold')]
print(first_gold_data)
输出:1984 年洛杉矶奥运会,许海峰拿下中国奥运历史第一枚金牌。
4. 中国男女选手历年奖牌堆叠柱状图
python
运行
# 按年份、性别分组统计奖牌
gender_year=df_china_medal.groupby(['Year','Sex'])['Medal'].count().unstack()
plt.figure(figsize=(12,6))
gender_year.plot(kind='bar',stacked=True)
plt.title('中国奥运男女选手历年奖牌堆叠图')
plt.xlabel('奥运年份')
plt.ylabel('奖牌总数')
plt.legend(['女性','男性'])
plt.show()
结论:中国女运动员奖牌贡献长期高于男性,女子项目是夺金核心优势。
5. 中国十大优势项目饼图
python
运行
advantage_sports=df_china_medal['Sport'].value_counts().head(10)
plt.figure(figsize=(10,10))
advantage_sports.plot(kind='pie',autopct='%.2f%%',shadow=True)
plt.title('中国奥运奖牌最多十大优势项目')
plt.ylabel("")
plt.show()
跳水、乒乓球、体操、举重、射击为传统五大夺金王牌。
6. 中国获奖最多 Top10 运动员玫瑰图(pyecharts)
python
运行
top10_players=df_china_medal['Name'].value_counts().head(10)
# 玫瑰饼图
pie=(
Pie(init_opts=opts.InitOpts(width="800px",height="600px"))
.add(
series_name="获奖次数",
data_pair=[list(z) for z in zip(top10_players.index,top10_players)],
rosetype='radius'
)
.set_global_opts(title_opts=opts.TitleOpts(title="中国奥运获奖最多前10名运动员"))
)
pie.render_notebook()
# pie.render("中国顶尖运动员玫瑰图.html")
六、项目总结与分析结论
1. 全球层面
- 百年奥运男性参赛人数长期占绝对主导,女性参赛规模随时间持续提升;
- 运动员黄金参赛年龄集中在 22-28 岁,不同项目体型(BMI)差异明显;
- 美国综合体育实力断层领先,俄罗斯、中国、英法德组成第二梯队;
- 田径、游泳、体操是全球通用高奖牌项目,各国专项优势差异巨大。
2. 中国奥运发展分析
- 1984 洛杉矶奥运会实现金牌零的突破,夏季奥运奖牌总量持续攀升;
- 冬季奥运起步晚,2010 年后冰雪项目成绩快速崛起;
- 女子运动员奖牌贡献长期高于男性,女子竞技体育优势突出;
- 跳水、乒乓球、体操、举重、射击是我国传统王牌夺金项目;
- 李宁、郭晶晶、吴敏霞、王义夫、孙杨等运动员成为奥运历史奖牌标杆。
3. 项目拓展方向
- 区分金银铜奖牌单独统计,分析各国金牌含金量;
- 分时代对比奥运项目增减变化;
- 运动员身高体重与项目成绩相关性分析;
- 使用 pyecharts 制作全球国家奖牌地图;
- 构建机器学习模型预测各国奖牌数量。
七、完整项目源码说明
- 数据集:
athlete_events.csv、noc_regions.csv(可在 Kaggle Olympic Dataset 下载) - 运行环境:Anaconda / Jupyter Notebook
- 图表输出:matplotlib 静态图 + pyecharts 交互式 HTML 图表
- 适用场景:大数据课程作业、Python 数据分析毕设、个人练手实战
CSDN 博文配套标签
#Python数据分析 #pandas实战 #奥运会数据集 #matplotlib可视化 #pyecharts #大数据课程作业 #数据清洗
写作小贴士(发布 CSDN 优化)
- 插入代码块选择 Python 语言,高亮更美观;
- 把运行截图插入对应章节,图文结合阅读体验更好;
- 文末附上数据集下载渠道,提升文章收藏率;
- 增加目录导航,长文分段清晰,提升阅读时长。
更多推荐
所有评论(0)