大家好,欢迎来到 Crossin的编程教室 !
第14届 全国运动会刚刚在陕西西安圆满闭幕。1万多名来自全国各地的运动健儿在这里进行了角逐。
今天让我们利用Python来看看这次比赛的数据吧~
目录:
1. 数据采集
1.1. 比赛大项数据
1.2. 比赛小项数据
1.3. 代表团数据
1.4. 运动员数据
1.5. 决赛名次数据
2. 统计展示
2.1. 项目维度
2.2. 代表团维度
2.3. 运动员维度
全运会有个低调的官网,里面有非常详尽的数据,我这边用python直接从该网站采集了本届的各类数据,采集过程不做详细介绍了,大家看代码即可。
第十四届全运会信息发布系统:
https://info.2021shaanxi.com/
第十四届全运会信息发布系统 1.1. 比赛大项数据 比赛大项数据是指官网展示的一共49项大的比赛项目数据,主要包含项目ID和项目名称。
import requestsimport 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.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()大项-小项分布 前10 各大项参与人数
田径 和足球 是参与人数最多的项目,都多达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 pltimport 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()那都是通过什么项目获得的呢?
来自田径和游泳
3块奖牌获得者 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年的老将刘英姿再夺全运会飞碟多向金牌
出生1971年选手 2008年出生的小奖,有三个是青年组的选手。
出生于2008年的选手 金牌运动员年龄分布
1996年和2000年出生的金牌运动员最多,居然刚好差了4年(一届周期)
金牌运动员年龄分布 以上就是本次全运会数据分析的全部内容。数据分析可以有很多维度和展现方式,本文仅仅是选取了其中的一部分,你也可以尝试更多角度的分析。
获取文中相关数据和代码文件,可点击下方公众号名片,回复关键字
全运会
作者:道才
_ 往期文章推荐 _