[译] 使用 Pandas 对 Kaggle 数据集进行统计数据分析

有时,当遇到一个数据问题的时候,对于数据集,咱们必须首先深刻研究并了解它。了解它的性质,它的分布等等,这是咱们须要专一的领域。前端

今天,咱们将利用 Python Pandas 框架进行数据分析,并利用 Seaborn 进行数据的可视化。python

做为一名极客程序员,个人审美观念很低。Seaborn 对我来讲是一种很好的可视化工具,由于只须要坐标点便可。android

它在底层使用 Matplotlib 做为绘图引擎,使用默认的样式来设置图形,这使得它们看起来比我所能作的更漂亮。让咱们来看一下数据集,我会给你们展现一种看待不一样特征时的直观感觉。也许咱们能从中得到一些真知灼见呢!ios

没有鸡蛋就不能作煎蛋卷:数据集。

下面的分析中,我使用的是 120 年的奥运会 数据集,你能够经过点击这个连接来下载或阅读更多的相关信息。git

我是从 Kaggle 上免费下载该数据集的。若是你须要获取一个数据集来尝试一些新的 机器学习算法,来温习一些框架的 API,或者只是想要玩一下,Kaggle 是一个很棒的网站。程序员

我将只使用 CSV 文件中的 ‘athlete_events’,其中记录了自 1900 年以来的每一场奥运会比赛的运动员信息,即每一个参赛运动员出生地所属的国家,以及他们是否获奖等等。github

有趣的是, 文件中的 medals 列中有 85% 的数据是空的,因此平均只有 15% 的奥运会运动员得到了奖牌。 此外,还有一些运动员得到了不止一枚奖牌,这代表,在为数很少的奥运级别运动员中,只有更少的人能得到奖牌。因此他们的功劳是更大的!算法

开始分析:数据集是什么样的?

首先,在深刻了解该数据集以前,能够先经过一些直观数据来了解数据集的模式。好比数据集中有多少数据丢失了?数据有多少列?我想先从这些问题开始分析。后端

我在分析过程当中使用 Jupyter 笔记进行,我会为我运行的每段代码添加注释,以便你能够继续学习。bash

该 Jupyter 笔记能够在 这个仓库中 找到,你能够打开来看一下,并能够从任何一个地方开始。

我首先要作的是使用 Pandas 来加载数据,并检查它们的大小。

import pandas as pd
import seaborn as sns

df = pd.read_csv('athlete_events.csv')
df.shape
#(271116, 15)
复制代码

在这个例子中,数据集中有 15 个不一样的列,以及整整 271116 行!也就是超过 27 万的运动员数据!可是接下来我想知道实际上有多少不一样的运动员。还有,他们中有多少人赢得了奖牌?

为了查看这些数据,首先字数据集上调用 ‘list’ 函数列出行数据。咱们能够看到许多感兴趣的特征。

list(df)
#['ID','Name','Sex','Age','Height','Weight','Team','NOC','Games','Year','Season','City',
# 'Sport','Event','Medal']
复制代码

我能想到的一些事情是,咱们能够查看奥运会运动员的平均身高和体重,或者经过不一样的运动来划分他们。咱们还能够查看依赖于性别的两个变量的分布。咱们甚至还能够看到每一个国家有多少奖牌,将此做为时间序列,来查看整个二十世纪文明的兴衰。

可能性是无限的!但首先让咱们来解决这个难题:咱们的数据集有多完整?

def NaN_percent(df, column_name):
    row_count = df[column_name].shape[0]
    empty_values = row_count - df[column_name].count()
    return (100.0*empty_values)/row_count
for i in list(df):
    print(i +': ' + str(NaN_percent(df,i))+'%')  
''' 0% incomplete columns omitted for brevity. Age: 3.49444518214% Height: 22.193821095% Weight: 23.191180159% Medal: 85.3262072323% --Notice how 15% of athletes did not get any medals '''
复制代码

在序列数据上使用 Pandas 的计数方法能够获得非空行的数量。而经过查看 shape 属性,能够查看到总的行数,无论它们是否为空。

以后就是减法和除法的问题了。咱们能够看到只有四栏的属性不完整:身高、体重、年龄和奖牌。

奖牌属性的不完整是由于一个运动员可能实际上并无赢得奖牌,因此能够预料到这条数据是不彻底的。然而,在体重、身高和年龄的方面,不完整的数据让咱们面临着至关大的挑战。

我试着用不一样的年份对这些数据行进行过滤,但这种不完整性彷佛随着时间的推移而保持一致,这让我以为多是有一些国家不提供运动员的这些相关数据。

开始咱们真正的分析: 奖牌状况是怎样的?

咱们问的第一个问题是,自 1900 年以来,有多少不一样的人得到过奖牌?下面的代码片断回答了这个问题:

total_rows = df.shape[0]
unique_athletes = len(df.Name.unique())
medal_winners = len(df[df.Medal.fillna('None')!='None'].Name.unique())

"{0} {1} {2}".format(total_rows, unique_athletes, medal_winners)

#'271116 134732 28202'
复制代码

正如你所看到的,在过去的 120 年里,大约有 13.5 万不一样的人参加了奥运会,可是只有 2.8 万多人得到了至少一枚奖牌。

得到奖牌比率大约是五分之一,还不错。但若是你考虑到许多人实际上会参加多个类别的运动,那就不那么乐观了。

既然咱们已经分析到这里了,那么在这 120 年里运动员们到底赢得了多少奖牌呢?

# 查看奖牌分布
print(df[df.Medal.fillna('None')!='None'].Medal.value_counts())
# 总共多少奖牌
df[df.Medal.fillna('None')!='None'].shape[0]
''' Gold 13372 Bronze 13295 Silver 13116 Total: 39783 '''
复制代码

不出所料,奖牌榜上的分布几乎是均匀的:得到的金牌、银牌和铜牌的数量几乎是相同的。

然而,总共颁发了近 3.9 万枚奖牌,这意味着若是你属于得到奖牌最多的那 20% 的运动员,那么你的平均奖牌数将超过 1 枚。

那么按照国家来进行分配呢?为了得到这些信息,能够运行下面的代码片断:

team_medal_count = df.groupby(['Team','Medal']).Medal.agg('count')
# 按照数量进行排列
team_medal_count = team_medal_count.reset_index(name='count').sort_values(['count'], ascending=False)
#team_medal_count.head(40) 用来显示第一行

def get_country_stats(country):
    return team_medal_count[team_medal_count.Team==country]
# get_country_stats('some_country') 得到对应国家的奖牌
复制代码

使用这个函数咱们能够获得某个国家得到的每种类型的奖牌数量,而经过获取 Pandas 数据帧头部以看到得到奖牌最多的国家。

有趣的是,奖牌数最多国家的第二名仍然是苏联,尽管它已经近 20 年没有出现了。

在全部类别中,第一名是美国,第三名是德国。我还观察了个人两个国家——阿根廷和克罗地亚,惊讶地发现克罗地亚已经赢得了 58 枚金牌,尽管这是从 1991 年(那是 1992 年的奥运会)以来的事情。

写一段代码做为练习,获取到某一个国家参加奥运会的不一样年份数据,我相信你能作到!

女性参与状况

我想到的另外一件有趣的事是,从这整个世纪以来,女性在奥运会上的表现如何?这段代码回答了这个问题:

unique_women = len(df[df.Sex=='F'].Name.unique())
unique_men = len(df[df.Sex=='M'].Name.unique())
women_medals = df[df.Sex=='F'].Medal.count()
men_medals = df[df.Sex=='M'].Medal.count()

print("{} {} {} {} ".format(unique_women, unique_men, women_medals, men_medals ))

df[df.Sex=='F'].Year.min()

#33808 100979 11253 28530 
#1900
复制代码

让我惊讶的是早在 1900 年就有女性参加了奥运会。然而,从历史上看,奥运会的男女比例是 3 比 1。惊讶于女性早在 1900 年就参加了奥运会,我决定查看一下整个时间段里面她们的参与人数。我终于用到了 Seaborn!

Female participation in the Olympics over time.

咱们能够看到,在过去的几十年里,女性的参与率一直在快速上升,从几乎为零上升到数千。然而,她们的参与率真的比男性增加得快吗?或者这只是世界人口的问题?为了解决这个问题,我作了第二副图:

f_year_count = df[df.Sex=='F'].groupby('Year').agg('count').Name
m_year_count = df[df.Sex=='M'].groupby('Year').agg('count').Name
(sns.scatterplot(data= m_year_count),
 sns.scatterplot(data =f_year_count))
复制代码

Female participation in the Olympics over time.

随时间推移,女性参与(橙色)对男性参与(蓝色)。

这一次,咱们能够清楚地看到这样一个模式的出现:女性的参与数量实际上正在快速地接近男性的数量!另外一件有趣的事情是:看到下面的小点了吗,在右边?我想那就是冬季奥运会!不管如何,对于女性表明来讲,这幅图看起来至关乐观,尽管尚未在哪一年中女性的参与者多于男性。

其它分析:身高和体重

我花了很长时间来查看身高和体重相关图,但没有获得任何有趣的结论。

  • 这两种属性在大多数运动中都是呈正态分布的
  • 在我所观察过的全部运动中,男性老是比女性更重和更高
  • 惟一有趣的变化彷佛是根据此项运动来能够分析两种性别之间的差异到底有多大。

若是你有任何有趣的想法能够用来分析体重和身高的数据,请告知我!我对每项运动的分组不够深刻,因此可能会有一些错误的解释。以上就是今天的内容,我但愿大家以为这个分析颇有趣,或者至少大家学到了一些 Pandas 或者数据分析的相关知识。

我把笔记放在了 GitHub 上,这样你就能够复制这个项目,能够作你本身的分析,而后提出一个 pull request(拉取请求)。

固然你能够获得全部的功劳!但愿大家在图形显示和视觉分析上作的比我要好。

第2部分关于运动的深刻理解 在这里能够找到。

能够 在 medium 上关注我 以获取更多软件开发和数据科学相关的教程、提示和技巧。 若是你真的喜欢这篇文章,和朋友分享吧!

若是发现译文存在错误或其余须要改进的地方,欢迎到 掘金翻译计划 对译文进行修改并 PR,也可得到相应奖励积分。文章开头的 本文永久连接 即为本文在 GitHub 上的 MarkDown 连接。


掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 AndroidiOS前端后端区块链产品设计人工智能等领域,想要查看更多优质译文请持续关注 掘金翻译计划官方微博知乎专栏

相关文章
相关标签/搜索