分析 120 年的 Kaggle 数据,中国何时站上奥运之巅?
本文读取了120年奥运会所有参赛纪录和比赛结果的数据源,从五个不同的方面解读出一些有趣的信息,适合对数据分析有兴趣的盆友阅读。
作者 | 倪家禹
责编 | 郭芮
2018年雅加达亚运会转眼闭幕了,中国代表队以132枚金牌、289枚奖牌的绝对优势,一骑绝尘,独领风骚,毫无悬念地再次霸占了金牌榜和奖牌榜首位。既然,区区亚洲已经阻止不了中国队收割奖牌的步伐,那么我们这回放眼世界,来研究一下奥运会吧。
这次的数据来自于Kaggle,一份涵盖120年奥运会所有参赛记录和比赛结果的数据,十分完整。我想通过这份数据,发现一些有趣的东西。
# -*- coding: utf-8 -*-
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')
from pyecharts import Bar
from pyecharts import Line
from pyecharts import Polar
from pyecharts import Overlap
from pylab import mpl
mpl.rcParams['font.sans-serif'] = ['SimHei'] # 指定默认字体
mpl.rcParams['axes.unicode_minus'] =False
#数据读入
data = pd.read_csv('./athlete_events.csv',engine='python')
data_mapping = pd.read_csv('./noc_regions.csv',engine='python')
#数据清洗
data_extract = pd.merge(data,data_mapping,how = 'left',
left_on = 'NOC',right_on = 'NOC')
del data_extract['notes']
data_extract = data_extract[data_extract['Season'] == 'Summer']
del data_extract['Season']
哪些国家站在奥运之巅?
由于百年来历史、政治、战争等因素,数据会略有出入
#得牌最多的国家
#金牌
data_gold = data_extract[data_extract['Medal'] == 'Gold']\
[['Games','region','Event','Medal']].drop_duplicates().\
groupby('region').count()['Medal'].to_frame().\
sort_values(by='Medal',ascending=False)
x1 = data_gold.index.tolist()[0:10]
y1 = data_gold.Medal.tolist()[0:10]
bar = Bar('奥运总金牌榜') #参数分别为标题和副标题
bar.add('金牌数', x1, y1,label_color = ['#5CACEE'],is_label_show=True)
bar.render('./图表/奥运总金牌榜.html')
上图数据统计了奥运总金牌数前十的国家。美国以1035块金牌遥遥领先,而且也是目前唯一一个金牌数超过1000枚的国家;俄罗斯以592枚次之,但俄罗斯的金牌数包括了当下与前苏联时期。金牌榜前五的其他国家——德国、英国、法国均在世界近现代历史上辉煌过或者仍然辉煌的国家。看来国家实力同样很大程度上影响了体育实力。
再来看看中国,以228枚金牌排名第6,但中国是从1984年才正式开始奥运征程的,所以从这点看,中国无疑是进步最快的国家。
data_medal = data_extract[['Games','region','Event','Medal']].drop_duplicates().\
groupby('region').count()['Medal'].to_frame().\
sort_values(by='Medal',ascending=False)
x2 = data_medal.index.tolist()[0:10]
y2 = data_medal.Medal.tolist()[0:10]
bar = Bar('奥运总奖牌榜')
bar.add('奖牌数', x2, y2,label_color = ['#DC143C'],is_label_show=True)
bar.render('./图表/奥运总奖牌榜.html')
奖牌榜和金牌榜的排名变化几乎不大,那些强大的一如既往的强大。中国退后了一个名次,以545枚奖牌名列第7。另外,中国、法国、英国、意大利在金牌榜中差距不大,而奖牌榜中,中国与其他三国的差距被拉大了。看来,中国在综合实力方面还有待提高呀。
1896年——2016年,四年一届的奥运会共应举办31届。由于战争、届间运动会等影响,到今天为止共有29届奥运会成功举办。那么哪些国家达成了全勤的成就呢?希腊,法国,意大利,英国,瑞士——这五个国家参加了全部29届奥运会。而中国,只参加了其中的13届,最早能追溯到1932年。后来在1958到1980年间,由于某几个众所周知的原因缺席了奥运会。1984年重回奥运舞台之后,中国就一发不可收拾地开启了崛起之路。
#各国参赛次数
data_c = data_extract[['Games','NOC']].drop_duplicates()['NOC']\
.value_counts().to_frame()
data_c.columns=['count']
data_c = pd.merge(data_c,data_mapping,how='left',left_index=True,right_on = 'NOC')
print('奥运会全勤的国家为:' + str(data_c[data_c['count']==29].region.tolist()))
print('中国参与了' + str(int(data_c[data_c['NOC']=='CHN']['count'])) + '次')
哪些运动员最牛?
研究完了国家,我们再来看看运动员。同样先上总金牌榜:
横轴起始有调整,下同
#哪些奥运选手得牌最多
#金牌
data_person_gold = data_extract[data_extract['Medal'] == 'Gold']\
[['Name','Medal']].groupby\
('Name').count()['Medal'].to_frame().\
sort_values(by='Medal',ascending=False)
x3 = data_person_gold.index.tolist()[0:11]
y3 = data_person_gold.Medal.tolist()[0:11]
bar = Bar('奥运个人金牌榜',width=1800,height=850) #参数分别为标题和副标题
bar.add('金牌数', x3, y3,label_color = ['#68228B'],is_label_show=True,
yaxis_rotate=55,is_convert=True,label_pos='right')
bar.render('./图表/奥运个人金牌榜.html')
排名第一的是美国著名游泳运动员迈克尔·菲尔普斯,以23块金牌问鼎。对!就是那位游得飞快,但屡次因为酒驾,嗑药,赌博被停赛的那家伙。
值得一提的是排名第二位的运动员,坐拥奥运会10块金牌。名字叫雷·尤瑞。估计大家都没听过。因为年代比较久远,他参加了1900-1908年的四次奥运会,跳远选手。据说早年患上小儿麻痹症,终日需要轮椅活动,最后获得了10次奥运冠军。这真是一个励志的故事!
继续看奖牌榜:
data_person_medal = data_extract[['Name','Medal']].groupby\
('Name').count()['Medal'].to_frame().\
sort_values(by='Medal',ascending=False)
x4 = data_person_medal.index.tolist()[0:11]
y4 = data_person_medal.Medal.tolist()[0:11]
bar = Bar('奥运个人奖牌榜',width=1800,height=850)
bar.add('奖牌数', x4, y4,label_color = ['#EEDC82'],is_label_show=True,
yaxis_rotate=55,is_convert=True,label_pos='right')
bar.render('./图表/奥运个人奖牌榜.html')
研究了一下,这些摘牌最多的运动员,绝大多数都是田径和游泳两大领域的。那么是不是田径和游泳是制霸奥运的关键?这个我们稍后研究。
#奥运会参与次数最多
data_person_max = data_extract[['Games','Name']].drop_duplicates()\
.groupby('Name')['Games'].count().to_frame().\
sort_values(by='Games',ascending=False)
print('参加奥运最多的选手为:' + str(data_person_max.Games.index[0]))
#年龄最大的运动员
data_age_max = data_extract[['Name','Sport','Age','Year']].drop_duplicates().\
sort_values(by='Age',ascending=False)
print(data_age_max[data_age_max['Sport']!='Art Competitions'][0:2])
其中年龄最大的运动员,72岁仍参赛。
Oscar Swahn:瑞典射击运动员,参加1920年比利时安特卫普奥运会,成为奥运历史上参赛年龄最大的运动员。获得过3金,1银,1铜。
Arthur von Pongracz:1936年参加柏林奥运会时,同样72岁,项目是花样骑术。
得田泳者是否得奥运?
我们取近五届奥运会金牌榜霸主美、中、俄三国的数据,分析在每个国家夺得的金牌数中,田泳项目占比有多高。
#田径和游泳是否决定奥运会成绩
data_gold_all = data_extract[data_extract['Medal'] == 'Gold'][['Year','Event','Medal']]\
.drop_duplicates().groupby('Year').count().reset_index()
del data_gold_all['Event']
data_gold_all.columns = ['Year','Medal_all']
data_gold_country_cat = data_extract[data_extract['Medal'] == 'Gold'][['Year','region','Event','Medal']]\
.drop_duplicates().groupby(['Year','region']).count().reset_index()
del data_gold_country_cat['Event']
data_gold_together = pd.merge(data_gold_country_cat,data_gold_all,how = 'left',
left_on = 'Year',right_on = 'Year')
data_gold_country_cat = data_extract[data_extract['Medal'] == 'Gold']\
[data_extract['Sport'].isin(['Athletics','Swimming'])]\
[['Year','region','Event','Medal']]\
.drop_duplicates().groupby(['Year','region']).count().reset_index()
del data_gold_country_cat['Event']
data_gold_country_cat.columns = ['Year','region','Medal_AS']
data_gold_together = pd.merge(data_gold_together,data_gold_country_cat,
how = 'left',on = ['Year','region'])
data_gold_together = data_gold_together.fillna(0)
data_gold_together['Medal_other'] = data_gold_together['Medal'] - data_gold_together['Medal_AS']
data_gold_together['Medal_AS_per'] = data_gold_together['Medal_AS']/data_gold_together['Medal']
data_gold_together2 = data_gold_together[data_gold_together['region'].isin(['USA','China','Russia'])]
data_gold_together2 = data_gold_together[data_gold_together['Year'] >=2000]
year = data_gold_together2.Year.unique().tolist()
v_p_usa = data_gold_together2[data_gold_together2['region'] =='USA'].Medal_AS_per.tolist()
v_p_china = data_gold_together2[data_gold_together2['region'] =='China'].Medal_AS_per.tolist()
v_p_russia = data_gold_together2[data_gold_together2['region'] =='Russia'].Medal_AS_per.tolist()
line = Line("近五届奥运会田泳项目金牌占比",'取美,中,俄三国',width=800)
line.add("美国", year, v_p_usa)
line.add("中国", year, v_p_china)
line.add("俄罗斯", year, v_p_russia)
line.render('./图表/各国近五届奥运会田泳项目金牌占比.html')
果然,美国队田泳项目占其金牌总数的60%左右。而俄罗斯,其田泳项目对金牌数的贡献逐届增加,至于2016年的“零”!那是因为被禁赛了。至于中国,从往届来看貌似田泳向来不是强项。结果说明,田泳项目由于奖牌产量大,确实对总成绩有不小的贡献。但也并不是绝对,奥运会毕竟是一个综合性的体育比赛。
主场优势真的存在吗?
这里取近9届奥运会主办国的表现来观察。统计其主办届及前后两届,共三次奥运会的金牌数:
data_home_dict = {
'中国':[32,51,38],
'英国':[19,29,27],
'澳大利亚':[9,16,17],
'希腊':[4,6,0],
'美国(亚特兰大)':[37,44,37],
'西班牙':[1,13,5],
'韩国':[6,12,12],
'美国(洛杉矶)':[0,83,36],
'苏联':[49,80,0]
}
data_home = pd.DataFrame(data_home_dict,index=['前一届','当届','后一届'])\
.T.stack().reset_index()
data_home.columns = ['国家','届','金牌数']
g = sns.FacetGrid(data_home, col="国家", col_wrap=3,
size=2.5,
aspect=1.2,sharex=False)
g.map(plt.plot, "届", "金牌数",
marker="o",linewidth = 2,color='orange')
g.set(xlim = (-1,3),
ylim = (0,85),
xticks = [0,1,2,3,4],
xticklabels = ["前一届", "当届","后一届"],
yticks = [0,20,40,60,80],
)
g.add_legend()
plt.savefig('./图表/主场优势真的存在吗.png',dpi=400)
plt.show()
折线图呈现中间高过两边的三角形,说明作为东道主成绩确实好过以往,甚至有的有超过50%的提升。所以,主场优势是真的存在的。
题外话:第五、第六张图,出现了两个数据为0的极端值。然后我发现主办国是美国和苏联。呵呵~我的历史老师告诉我,当初两个国家在冷战,而期间,双方又各举办了一届奥运会,对方的奥运会当然是不可能去捧场的……
中国的奥运会足迹
#中国奥运得牌数量变迁史
data_china = data_extract[data_extract['region']=='China']\
[['Year','region','Event','Medal']].drop_duplicates()\
[['Year','region','Medal']]
data_china.dropna(inplace=True)
data_china = data_china.groupby(['Year','Medal']).count()['region'].reset_index()
attr = data_china.Year.unique().tolist()
g = data_china[data_china['Medal']=='Gold'].region.tolist()
s = data_china[data_china['Medal']=='Silver'].region.tolist()
b = data_china[data_china['Medal']=='Bronze'].region.tolist()
bar = Bar("中国奥运成绩变迁史")
bar.add("铜牌", attr, b, is_stack=True,label_color = ['#EEB422'])
bar.add("银牌", attr, s, is_stack=True,label_color = ['#969696'])
bar.add("金牌", attr, g, is_stack=True,label_color = ['#8B5742'])
line = Line('中国奥运成绩变迁史')
line.add('金牌',attr, g, is_smooth=True,mark_point=["max"])
line.add('银牌',attr, s, is_smooth=True,mark_point=["max"])
line.add('铜牌',attr, b, is_smooth=True,mark_point=["max"])
overlap = Overlap()
overlap.add(bar)
overlap.add(line)
overlap.render('./图表/中国奥运成绩变迁史.html')
从1984年首次参赛以来一直在进步。巅峰为2008年北京奥运会,坐拥主场,获得了100枚奖牌。在2016年,出现了明显的滑铁卢,主要是金牌方面。
有些项目一直以来都是中国摘金夺银的有力保障,我们把这些强势项目的团队称之为“梦之队”。我们来看看中国有哪些“梦之队”。
下图分别统计金牌数和奖牌数:
#中国有哪些强势项目
data_china_dt = data_extract[data_extract['region']=='China']\
[['Year','region','Sport','Event','Medal']].drop_duplicates()\
[['Year','Sport','Medal']]
data_china_dt = data_china_dt[data_china_dt['Medal'] == 'Gold']
data_china_dt = data_china_dt.groupby(['Year','Sport']).count()['Medal'].reset_index()
data_china_dt_all = pd.DataFrame(columns=data_china_dt['Year'].unique().tolist(),
index=data_china_dt.Sport.unique().tolist())
for st in data_china_dt['Year'].unique().tolist():
for i in data_china_dt[data_china_dt['Year'] == st][['Sport','Medal']].iterrows():
data_china_dt_all[st][i[1][0]] = i[1][1]
data_china_dt_all.fillna(0,inplace=True)
radius =data_china_dt_all.index.tolist()
polar = Polar('中国奥运强势项目', width=1200, height=800)
for r in data_china_dt_all.columns.tolist():
num = data_china_dt_all[r].tolist()
polar.add(str(r),num, radius_data=radius,type='barAngle', is_stack=True)
polar.render('./图表/中国奥运强势项目(金牌).html')
data_china_dt = data_extract[data_extract['region']=='China']\
[['Year','region','Sport','Event','Medal']].drop_duplicates()\
[['Year','Sport','Medal']]
#data_china_dt = data_china_dt[data_china_dt['Medal'] == 'Gold']
data_china_dt = data_china_dt.groupby(['Year','Sport']).count()['Medal'].reset_index()
data_china_dt_all = pd.DataFrame(columns=data_china_dt['Year'].unique().tolist(),
index=data_china_dt.Sport.unique().tolist())
for st in data_china_dt['Year'].unique().tolist():
for i in data_china_dt[data_china_dt['Year'] == st][['Sport','Medal']].iterrows():
data_china_dt_all[st][i[1][0]] = i[1][1]
data_china_dt_all.fillna(0,inplace=True)
radius =data_china_dt_all.index.tolist()
polar = Polar('中国奥运强势项目', width=1600, height=1000)
for r in data_china_dt_all.columns.tolist():
num = data_china_dt_all[r].tolist()
polar.add(str(r),num, radius_data=radius,type='barAngle', is_stack=True)
polar.render('./图表/中国奥运强势项目(奖牌).html')
最强大的无疑是中国跳水梦之队,几乎可以摘得每届奥运会所有的金银牌,而跳水运动项目又十分多。其次,乒乓球,这个项目同样天下无敌,可惜项目少了点,所以奖牌也少了点。同样还有体操,射击,举重等,中国都曾不同程度地制霸赛场。所以,相比于老牌强队专注于田泳,中国的奥运之路乃是遍地开花,而且哪怕是田径和游泳,目前也走上了崛起之路。
我们相信在不久的将来,中国终将会站上奥运之巅,睥睨天下。
作者:数据侠倪家禹,城市数据团特约撰稿人,数据分析师(python)微专业学员,喜欢用数据挖掘生活中的小秘密。对数据研究有着敏锐的洞察力,善于把复杂的问题简单化,简单的问题流程化。希望大家通过数据感受生活的魅力。
声明:本文为公众号数据团学社投稿,版权归对方所有。
苹果手机的微信改版了,
想快速看到CSDN的热乎文章,
赶快把CSDN公众号设为星标吧,
打开公众号,点击“设为星标”就可以啦!
安卓手机的用户,
点击公众号右上角小人,就可以置顶啦。
推荐阅读:
2018 AI开发者大会
◆
只讲技术,拒绝空谈
◆
2018 AI开发者大会首轮重磅嘉宾及深度议题现已火热出炉,扫码抢“鲜”看。国庆特惠,购票立享 5 折优惠!
点击“阅读原文”,也可立即报名。