用python带你一览2021陕西全运会数据
大家好,欢迎来到 Crossin的编程教室 !
第14届全国运动会刚刚在陕西西安圆满闭幕。1万多名来自全国各地的运动健儿在这里进行了角逐。
今天让我们利用Python来看看这次比赛的数据吧~
目录:
1. 数据采集
1.1. 比赛大项数据
1.2. 比赛小项数据
1.3. 代表团数据
1.4. 运动员数据
1.5. 决赛名次数据
2. 统计展示
2.1. 项目维度
2.2. 代表团维度
2.3. 运动员维度
1. 数据采集
全运会有个低调的官网,里面有非常详尽的数据,我这边用python直接从该网站采集了本届的各类数据,采集过程不做详细介绍了,大家看代码即可。
第十四届全运会信息发布系统:
https://info.2021shaanxi.com/
1.1. 比赛大项数据
比赛大项数据是指官网展示的一共49项
大的比赛项目数据,主要包含项目ID
和项目名称
。
import requests
import pandas as pd
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36",
}
# 大项
url = 'https://info.2021shaanxi.com/Data/commonCode/disciplineList.json'
r = requests.get(url, headers= headers)
data = r.json()
disciplineList = pd.DataFrame(data)
disciplineList.replace(r'-','',regex=True,inplace=True)
disciplineList.sample(5)
1.2. 比赛小项数据
比赛小项是指具体的比赛项目,比如大项射箭—男子—男子反曲弓个人项目
,本次一共有427
个小项。
# 小项
url = 'https://info.2021shaanxi.com/Data/commonCode/event.json'
r = requests.get(url, headers= headers,)
data = r.json()
items = []
for key in data.keys():
for key1 in data[key].keys():
item = data[key][key1][0]
items.append(item)
event = pd.DataFrame(items)
event.replace(r'-','',regex=True,inplace=True)
event.sample(5)
1.3. 代表团数据
代表团是指省、机构组织或者个人,比如北京市、湖北省,北京体育大学组织或者个人(如游泳、山地车等就有以个人名义参加的运动员),一共58
个代表团组织。
# 代表团
url = 'https://info.2021shaanxi.com/Data/commonCode/delegation.json'
r = requests.get(url, headers= headers, )
data = r.json()
items = []
for key in data.keys():
item = data[key][0]
items.append(item)
delegation = pd.DataFrame(items)
delegation.replace(r'-','',regex=True,inplace=True)
delegation.sample(5)
1.4. 运动员数据
运动员一共12434人,但实际有参与项目的12037
人。
# 运动员
items = []
for Id in disciplineList['Id']:
url = f'https://info.2021shaanxi.com/api/participant/list?discipline={Id}'
r = requests.get(url, headers= headers)
data = r.json()
item = data['data']
items.extend(item)
AthleteList = pd.DataFrame(items)
AthleteList.replace(r'-','',regex=True,inplace=True)
AthleteList['event_count'] = AthleteList.EventEntry.apply(len)
# 匹配大项
AthleteList = AthleteList.merge(disciplineList[['Id', 'CHI_Description']],
right_on='Id', left_on='DisciplineCode', how='left')
# 匹配组织
AthleteList = AthleteList.merge(delegation[['Id', 'CHI_Description']],
left_on='OrganisationCode', right_on='Id', how='left')
AthleteList.sample(5)
1.5. 决赛名次数据
决赛名次其实就是每个项目比赛结果数据,金银铜牌
获得者的信息,后续我们可以根据这份数据来看看体育强省在哪里!
# 决赛数据
dataList = []
# 决赛日期(数据是9-25号采集的,所以截止选的9-24日)
dateList = pd.date_range('2021-07-12','2021-09-24').strftime('%Y%m%d')
for date in dateList:
url = f'https://info.2021shaanxi.com/Data/Medal/Daily/{date}/data.json'
r = requests.get(url, headers= headers)
try:
data = r.json()
data = pd.DataFrame(data)
data.replace(r'-','',regex=True,inplace=True)
def get_BirthDate(x):
if len(x)==1:
return x[0]['BirthDate']
def get_AthleteCode(x):
if len(x)==1:
return x[0]['AthleteCode']
data['BirthDate'] = data['Members'].apply(get_BirthDate)
data['AthleteCode'] = data['Members'].apply(get_AthleteCode)
dataList.append(data)
except :
continue
data = pd.concat(dataList)
df = data[['Date', 'EventCode', 'MedalRank', 'OrganisationCode', 'Gender',
'Name', 'BirthDate', 'AthleteCode']]
# 匹配组织
df = df.merge(delegation[['Id', 'CHI_Description']],
left_on='OrganisationCode', right_on='Id', how='left')
# 匹配小项
df = df.merge(event[['CHI_Description','Code', 'Discipline', 'Team_Event']],
right_on='Code', left_on='EventCode', how='left')
# 匹配大项
df = df.merge(disciplineList[['Id', 'CHI_Description']],
right_on='Id', left_on='Discipline', how='left')
# 字段筛选
df = df[['Date', 'CHI_Description', 'CHI_Description_y', 'Gender', 'MedalRank',
'Name', 'CHI_Description_x','BirthDate', 'AthleteCode', 'Team_Event']]
df.sample(5)
2. 统计展示
本部分我们将进行项目统计、代表团(尤其是省级行政区代表团)统计以及运动员统计三部分展开。
2.1. 项目维度
本届全运会大项目一共49
个,小项目一共427
个,具体分布如下:
大项-小项分布
田径、游泳是拥有小项最多的,其中田径的小项高达52
种、游泳的小项也有高达37
种。热度较高的跳水小项也很多有17
种,乒乓球则有7种小项。
# 筛选全小项
event = event[(event['Event'].str.len()>0)&(event['Gender'].str.len()>0)]
# 匹配大项名称
Discipline_event_Num = event.merge(disciplineList, left_on='Discipline', right_on='Id').groupby('CHI_Description_y')['Code'].nunique().to_frame('小项数')
Discipline_event_Num.sort_values(by='小项数', ascending=False).reset_index()
各大项参与人数
田径和足球是参与人数最多的项目,都多达1000
人以上。不过,大多数的团体项目参与人数都是较多的无疑了。
# 各项目运动员数
Discipline_Num = AthleteList.groupby('CHI_Description_x')['AthleteCode'].nunique().to_frame('人数')
Discipline_Num.sort_values(by='人数', ascending=False).reset_index()
import matplotlib.pyplot as plt
import numpy as np
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
# 设置柱状图颜色
colors = ['turquoise', 'coral']
labels = Discipline_Num.index
y = Discipline_Num['人数']
x = np.arange(len(labels))
width = 0.35
fig, ax = plt.subplots(figsize=(8,16))
rects1 = ax.barh(x + width/2, y, color=colors[1], edgecolor='grey')
ax.set_title('各项目参赛人数', fontsize=16)
y_pos = np.arange(len(labels))
ax.set_yticks(y_pos)
ax.set_yticklabels(labels, fontsize=12)
# 显示数据标签
ax.bar_label(rects1, padding=3)
fig.tight_layout()
# 边框隐藏
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
# ax.spines['bottom'].set_visible(False)
ax.spines['left'].set_visible(False)
plt.show()
fig.savefig('各项目参赛人数.png')
个人团体分布
在全部小项目中有139
项约占32.6%的项目是团体类的(比如足球、乒乓球混双等),另外288
项占比67.54
的项目是个人赛。
# 个人团体分布 (Discipline)
Team_Event_Num = event.groupby('Team_Event')['Code'].nunique().to_frame('小项数')
labels = Team_Event_Num.index
sizes = Team_Event_Num['小项数']
explode = (0, 0.1,)
fig1, ax1 = plt.subplots(figsize=(6,5))
patches, texts, autotexts = ax1.pie(sizes, explode=explode, labels=labels, autopct='%1.1f%%',
shadow=True, startangle=90)
ax1.axis('equal')
ax1.set_title('各比赛小项个人团体分布', fontsize=16)
# 重新设置字体大小
proptease = fm.FontProperties()
proptease.set_size('large')
plt.setp(autotexts, fontproperties=proptease)
plt.setp(texts, fontproperties=proptease)
plt.show()
性别分布
有207
个项目是男性项目,193
个项目是女性项目,混合类的有21
种,而不分男女共6种(马术比赛)
# 性别分布
Gender_Event_Num = event.groupby('Gender')['Code'].nunique().to_frame('小项数')
labels = Gender_Event_Num.index
sizes = Gender_Event_Num['小项数']
explode = (0, 0., 0, 0, )
fig1, ax1 = plt.subplots(figsize=(8,7))
patches, texts, autotexts = ax1.pie(sizes, explode=explode, labels=labels, autopct='%1.1f%%',
shadow=True, startangle=90)
ax1.axis('equal')
ax1.set_title('各比赛小项性别分布', fontsize=16)
# 重新设置字体大小
proptease = fm.FontProperties()
proptease.set_size('large')
plt.setp(autotexts, fontproperties=proptease)
plt.setp(texts, fontproperties=proptease)
plt.show()
2.2. 代表团维度
一共58个代表团,其中34个省级行政区+4个协会、13个俱乐部、2个学校等,其中OO
是联合队(奥运会联合队)
各类代表团分布
Type | 数量 | |
---|---|---|
0 | D | 38 |
1 | CLUB | 13 |
2 | RO | 3 |
3 | SCHOOL | 2 |
4 | GR | 1 |
5 | OO | 1 |
# 代表团类型
Type_delegation_Num = delegation.groupby('Type')['Id'].nunique().to_frame('数量')
Type_delegation_Num.sort_values(by='数量', ascending=False).reset_index()
代表团人数对比
虽然说有58个代表团,实际参赛的代表团53
个,比如我们的台湾省并没有参与,希望他们能早日参与进来。在这53个代表团中,我们按照省级行政区和其他分类对比看看。
省级行政区
山东、广东、江苏、上海和陕西是本次参数选手最多的省份
其他
天津体育学院作为高校,有24名参数选手,北京体育大学则有2名。
代表团参与大项数
作为东道主的陕西,本届全运会参与了高达47/49个大类,此外参赛人数较多的江苏、广东和上海均参加了44个大类。
Organisation_Discipline_Num = AthleteList.groupby('CHI_Description_y')['CHI_Description_x'].nunique().to_frame('大项数')
Organisation_Discipline_Num.sort_values(by='大项数', ascending=False).reset_index()
代表团奖牌数
注:后续章节数据截止时间为9月24日24点。。
在总奖牌数排名中,山东、广东、江苏、浙江和上海高居前列(这联合队
未进行细分到省份哈)
Organisation_Medal_Num = df.pivot_table(values='Name',margins=True,index='CHI_Description_x',columns='MedalRank',aggfunc='count').fillna(0)
Organisation_Medal_Num = Organisation_Medal_Num.sort_values(by='All', ascending=False).reset_index()
Organisation_Medal_Num.columns = ['代表团','金牌','银牌','铜牌','总奖牌']
Organisation_Medal_Num.convert_dtypes()
代表团 | 金牌 | 银牌 | 铜牌 | 总奖牌 |
---|---|---|---|---|
All | 331 | 331 | 391 | 1053 |
山东 | 35 | 38 | 35 | 108 |
广东 | 30 | 26 | 48 | 104 |
江苏 | 27 | 27 | 31 | 85 |
浙江 | 25 | 25 | 28 | 78 |
上海 | 16 | 19 | 23 | 58 |
四川 | 14 | 17 | 20 | 51 |
陕西 | 16 | 13 | 20 | 49 |
福建 | 18 | 15 | 16 | 49 |
湖北 | 12 | 16 | 15 | 43 |
联合队 | 35 | 4 | 1 | 40 |
辽宁 | 7 | 13 | 17 | 37 |
北京 | 10 | 12 | 12 | 34 |
天津 | 8 | 8 | 16 | 32 |
河北 | 8 | 10 | 13 | 31 |
河南 | 10 | 8 | 13 | 31 |
湖南 | 13 | 11 | 7 | 31 |
安徽 | 6 | 9 | 9 | 24 |
山西 | 4 | 7 | 10 | 21 |
内蒙古 | 7 | 4 | 7 | 18 |
云南 | 5 | 7 | 5 | 17 |
江西 | 2 | 6 | 5 | 13 |
广西 | 2 | 6 | 4 | 12 |
吉林 | 2 | 3 | 7 | 12 |
新疆 | 2 | 5 | 3 | 10 |
甘肃 | 2 | 4 | 3 | 9 |
贵州 | 2 | 2 | 5 | 9 |
重庆 | 1 | 6 | 2 | 9 |
黑龙江 | 1 | 4 | 4 | 9 |
香港 | 1 | 0 | 5 | 6 |
前卫体协 | 2 | 2 | 1 | 5 |
海南 | 4 | 1 | 0 | 5 |
西藏 | 3 | 0 | 2 | 5 |
青海 | 0 | 3 | 1 | 4 |
贵州轮迹自行车运动俱乐部 | 1 | 0 | 1 | 2 |
火车头体协 | 0 | 0 | 1 | 1 |
澳门 | 0 | 0 | 1 | 1 |
代表团夺金数(金牌榜)
金牌榜中,山东最强,其次是联合队,接着依次是广东、江苏、浙江和福建。
我们发现联合队基本都是金牌,这也是为什么本届的奥运联合队会机制会被网友吐槽的原因!
排名 | 代表团 | 金牌 | 银牌 | 铜牌 | 总奖牌 |
---|---|---|---|---|---|
1 | 山东 | 35 | 38 | 35 | 108 |
2 | 联合队 | 35 | 4 | 1 | 40 |
3 | 广东 | 30 | 26 | 48 | 104 |
4 | 江苏 | 27 | 27 | 31 | 85 |
5 | 浙江 | 25 | 25 | 28 | 78 |
6 | 福建 | 18 | 15 | 16 | 49 |
7 | 上海 | 16 | 19 | 23 | 58 |
8 | 陕西 | 16 | 13 | 20 | 49 |
9 | 四川 | 14 | 17 | 20 | 51 |
2.3. 运动员维度
这部分我们主要看看运动员年龄分布,感受一下咱们新生代力量。
我们一共有668
名运动员获得了奖牌,其中金牌获得者208
人,银牌获得者215
人,铜牌获得者270
人。
(注意:本部分不考虑团体赛)
参数运动员性别分布
全部参赛选手中,男性占比52.2%
,女性占比47.8%
,总的来说是非常平衡的了。
# 参赛选手性别分布
Gender_Num = AthleteList.groupby('GenderCode')['AthleteCode'].nunique().to_frame('人数')
奖牌最多的运动员
个人单项赛事奖牌最多的有5个人,均为3
块奖牌
运动员 | 性别 | 金牌 | 银牌 | 铜牌 | 总奖牌 | |
---|---|---|---|---|---|---|
1 | 汪顺 | M | 3 | 0 | 0 | 3 |
2 | 张子扬 | M | 2 | 1 | 0 | 3 |
3 | 王春雨 | W | 2 | 1 | 0 | 3 |
4 | 季新杰 | M | 1 | 2 | 0 | 3 |
5 | 覃海洋 | M | 1 | 1 | 1 | 3 |
Athlete_Medal_Num = df[df['Team_Event']=='N'].pivot_table(values='CHI_Description',margins=True,index=['Name','Gender'],columns='MedalRank',aggfunc='count').fillna(0)
Athlete_Medal_Num = Athlete_Medal_Num.sort_values(by=['All',1,2,3], ascending=[False,False,False,False]).reset_index()
Athlete_Medal_Num.columns = ['运动员','性别','金牌','银牌','铜牌','总奖牌']
Athlete_Medal_Num.convert_dtypes().head()
那都是通过什么项目获得的呢?
来自田径和游泳
nameList = Athlete_Medal_Num[Athlete_Medal_Num['总奖牌']>=3]['运动员']
df[df['Name'].str.contains('|'.join(nameList))].sort_values(by = 'Name')
事实上,来自浙江的1994年的汪顺已经收获了含团体赛在内的6
枚金牌!
金牌最多的运动员
金牌数最多的就是汪顺了
获得金牌最多的女子运动员则是田径选手王春雨,来自安徽的1995年跑步健将!
获奖运动员年龄分布
本届全运会,大部分的获奖运动员出生年份集中在1994年-2000年。
我们发现居然还有1971年的51岁选手!!,最小的则是2008年的13岁朋友!!相差接近4倍~
时隔12年 “七战”1971年的老将刘英姿再夺全运会飞碟多向金牌
2008
年出生的小奖,有三个是青年组的选手。
金牌运动员年龄分布
1996年和2000年出生的金牌运动员最多,居然刚好差了4年(一届周期)
以上就是本次全运会数据分析的全部内容。数据分析可以有很多维度和展现方式,本文仅仅是选取了其中的一部分,你也可以尝试更多角度的分析。
获取文中相关数据和代码文件,可点击下方公众号名片,回复关键字 全运会
作者:道才
_往期文章推荐_