[譯] 使用 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前端後端區塊鏈產品設計人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章
相關標籤/搜索