文章简介

大家好,今天分享一套完整奥运会运动员数据集数据分析实战项目,基于athlete_events.csvnoc_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. 读取两份数据集

数据集说明:

  1. athlete_events.csv:每条记录代表一名运动员单届奥运参赛记录,包含年龄、身高、体重、项目、奖牌、年份、性别等核心字段
  2. 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. 缺失值填充策略

  1. region(国家)缺失填充Unknown
  2. Medal 奖牌空值填充No Medal(区分金银铜无奖牌)
  3. Age 年龄:均值填充
  4. Height 身高:中位数填充(避免极端身高干扰)
  5. 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. 历史国家统一映射说明

数据中存在历史政权拆分 / 合并,统一归类方便统计:

  1. Russia:苏联 URS、独联体 EUN、俄罗斯 RUS 统一归为 Russia
  2. 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. 全球层面

  1. 百年奥运男性参赛人数长期占绝对主导,女性参赛规模随时间持续提升;
  2. 运动员黄金参赛年龄集中在 22-28 岁,不同项目体型(BMI)差异明显;
  3. 美国综合体育实力断层领先,俄罗斯、中国、英法德组成第二梯队;
  4. 田径、游泳、体操是全球通用高奖牌项目,各国专项优势差异巨大。

2. 中国奥运发展分析

  1. 1984 洛杉矶奥运会实现金牌零的突破,夏季奥运奖牌总量持续攀升;
  2. 冬季奥运起步晚,2010 年后冰雪项目成绩快速崛起;
  3. 女子运动员奖牌贡献长期高于男性,女子竞技体育优势突出;
  4. 跳水、乒乓球、体操、举重、射击是我国传统王牌夺金项目;
  5. 李宁、郭晶晶、吴敏霞、王义夫、孙杨等运动员成为奥运历史奖牌标杆。

3. 项目拓展方向

  1. 区分金银铜奖牌单独统计,分析各国金牌含金量;
  2. 分时代对比奥运项目增减变化;
  3. 运动员身高体重与项目成绩相关性分析;
  4. 使用 pyecharts 制作全球国家奖牌地图;
  5. 构建机器学习模型预测各国奖牌数量。

七、完整项目源码说明

  1. 数据集:athlete_events.csvnoc_regions.csv(可在 Kaggle Olympic Dataset 下载)
  2. 运行环境:Anaconda / Jupyter Notebook
  3. 图表输出:matplotlib 静态图 + pyecharts 交互式 HTML 图表
  4. 适用场景:大数据课程作业、Python 数据分析毕设、个人练手实战

CSDN 博文配套标签

#Python数据分析 #pandas实战 #奥运会数据集 #matplotlib可视化 #pyecharts #大数据课程作业 #数据清洗

写作小贴士(发布 CSDN 优化)

  1. 插入代码块选择 Python 语言,高亮更美观;
  2. 把运行截图插入对应章节,图文结合阅读体验更好;
  3. 文末附上数据集下载渠道,提升文章收藏率;
  4. 增加目录导航,长文分段清晰,提升阅读时长。

更多推荐