前言
最近剛讀完《利用 Python 進(jìn)行數(shù)據(jù)分析》,知識(shí)點(diǎn)還不是很牢固矮固,于是想找些數(shù)據(jù)練手失息,剛好自己是個(gè)籃球迷,于是找了些 NBA 數(shù)據(jù)統(tǒng)計(jì)網(wǎng)站作為數(shù)據(jù)的來源档址,并借此來走一遍數(shù)據(jù)分析的流程盹兢。
背景
三雙
通常情況,是指在一場比賽中守伸,得分绎秒,籃板,助攻尼摹,搶斷见芹,蓋帽中,有三項(xiàng)技術(shù)統(tǒng)計(jì)達(dá)到兩位數(shù)蠢涝,就被稱為「三雙」(不考慮失誤上雙的情況)玄呛。
豪華型三雙 & 經(jīng)濟(jì)型三雙
并沒有明確標(biāo)準(zhǔn)來定義「豪華型」或「經(jīng)濟(jì)型」,下文會(huì)以平均得分作為指標(biāo)惠赫,平均得分越高就越「豪華」,反之則越「經(jīng)濟(jì)」(實(shí)際上可以根據(jù)三雙數(shù)據(jù)的標(biāo)準(zhǔn)差來判斷選擇以得分作為標(biāo)準(zhǔn)的合理性)故黑。
數(shù)據(jù)來源
來自 Basketball Refference儿咱,篩選了 1983-84 賽季至本賽季(2016-2017)的常規(guī)賽這段時(shí)間所有球員的三雙數(shù)據(jù)庭砍,查詢到結(jié)果共有 1449 人次獲得過三雙或以上(也會(huì)有四雙)。
數(shù)據(jù)抓取
雖然網(wǎng)站提供了 CSV 文本格式混埠,但似乎并不支持下載(需要自己手動(dòng)復(fù)制)怠缸,此外纪他,數(shù)據(jù)太詳細(xì)了帘皿,對于這次的分析來說,無效值太多了之碗,與其在數(shù)據(jù)處理的過程中被繁多的數(shù)據(jù)項(xiàng)「轟炸」吏颖,還不如在抓取的過程中將符合分析需求的數(shù)據(jù)項(xiàng)篩選出來搔体。
先來看看 Basketball Refference 都提供了哪些數(shù)據(jù):
對于此次的分析來說,我們只需要抓取最基礎(chǔ)的數(shù)據(jù)項(xiàng)半醉,如名字(Player)疚俱、得分(PTS)、籃板(TRB)缩多、助攻(AST)呆奕、搶斷(STL)、蓋帽(BLK)衬吆,當(dāng)然梁钾,還可以根據(jù)自己的分析需求加上其他數(shù)據(jù)項(xiàng)。
確定了需要抓取的數(shù)據(jù)項(xiàng)后逊抡,再確定一下用于抓取的工具姆泻,這里我選擇了 Python + PySpider 框架。
PySpider
PySpider 是國內(nèi)大神 binux 開發(fā)的一套簡單易用并且功能強(qiáng)大的爬蟲框架秦忿,支持多線程爬取麦射、JS 動(dòng)態(tài)解析,提供 WebUI灯谣、出錯(cuò)重試潜秋、定時(shí)爬取等功能,非常人性化胎许。
PySpider 官網(wǎng):http://docs.pyspider.org/
代碼展示
閱讀 PySpider 文檔和 Sample Code峻呛,并作出修改:
1. 一頁獲取多個(gè)結(jié)果:PySpider 是有提供 url 去重功能的(避免重復(fù)抓取 url),而這個(gè)例子中的數(shù)據(jù)是以表格形式展示的(每條數(shù)據(jù)的 url 是相同的)辜窑,所以需要人為地修改每條數(shù)據(jù)的 url钩述,方法是在 url 的結(jié)尾加上一個(gè)數(shù)字標(biāo)記「#i」。PySpider API 里提供了 self.send_message() 的方法穆碎,最后也別忘記設(shè)置 on_message()牙勘。
2. 設(shè)置逐頁爬取:response.doc 支持 css selector,所以在找到「下一頁」的標(biāo)簽 url 后方面,將讓它重新執(zhí)行 index_page()放钦,實(shí)現(xiàn)逐頁爬取功能。
代碼在 PySpider 內(nèi)置的編輯器上執(zhí)行恭金,點(diǎn)擊藍(lán)色 save 保存代碼操禀,再點(diǎn)擊綠色的 run,就可以調(diào)試代碼能否正確爬取代碼横腿。若確認(rèn)數(shù)據(jù)就是自己想要的颓屑,可以回到 PySpider 的 Dashboard 上,將項(xiàng)目設(shè)置為 Debug 或 Running 狀態(tài)耿焊,再執(zhí)行 Run揪惦,數(shù)據(jù)就會(huì)進(jìn)行爬取了。
數(shù)據(jù)爬取完成后搀别,點(diǎn)擊 Dashboard 該項(xiàng)目的 Results丹擎,右上方便有 CSV 文件下載的選項(xiàng)了,這個(gè)就是我想要的歷年 NBA 三雙球員場次的數(shù)據(jù)了歇父。
數(shù)據(jù)清洗
網(wǎng)站爬蟲難免會(huì)爬取到一些無效值蒂培,在進(jìn)行分析之前,先要對數(shù)據(jù)進(jìn)行一番清理榜苫,避免影響數(shù)據(jù)分析的結(jié)果护戳。由于我有其他的分析項(xiàng)目,所以我在數(shù)據(jù)爬蟲的時(shí)候垂睬,也爬取了其他的數(shù)據(jù)項(xiàng)媳荒,但對于本例子的分析項(xiàng)目來說,這些數(shù)據(jù)項(xiàng)就是無效值驹饺,需要清除钳枕。另外,表格出現(xiàn)若干帶有空值的行赏壹,這也是無效值鱼炒,需要清理。另外蝌借,PySpider 也附加了一些無意義的列昔瞧,也需要清理一下。如下圖菩佑,紅框框住的行/列自晰,都是需要清洗掉的:
代碼展示
除了對無效值的清洗,數(shù)據(jù)清洗還包括對數(shù)據(jù)類型的轉(zhuǎn)換稍坯,通過 df.dtypes 指令可得知酬荞,例子中獲取到的 age 和 date 都是字符串?dāng)?shù)據(jù)類型,這樣就不方便進(jìn)行數(shù)值化統(tǒng)計(jì)(比如平均年齡)等操作了。所以在進(jìn)行分析前混巧,還需要對這兩列的數(shù)據(jù)類型進(jìn)行轉(zhuǎn)換糟把。
(P.S. 這兩數(shù)據(jù)項(xiàng)在本例子里本應(yīng)也是無效值,但作為展示數(shù)據(jù)清洗中的數(shù)據(jù)類型轉(zhuǎn)換牲剃,還是保留下來)
最后得出來的數(shù)據(jù)結(jié)果是:
至此雄可,本例子的數(shù)據(jù)清洗凿傅,先到這一步,實(shí)際上在其他項(xiàng)目中数苫,可能還需要進(jìn)行的數(shù)據(jù)清洗的操作有聪舒,填充空值、去除數(shù)據(jù)中多余的空格虐急、大小寫轉(zhuǎn)換箱残、異常值替換等等。由于篇幅限制止吁,就不展開討論了被辑。
數(shù)據(jù)分析
數(shù)據(jù)分析最重要的是分析目標(biāo),只有明確了分析目標(biāo)敬惦,才能明確下一步操作的思路盼理。回到本例子中俄删,是希望通過抓取的球員數(shù)據(jù)宏怔,分析出誰拿的三雙最「豪華」,誰的最「經(jīng)濟(jì)」畴椰。
根據(jù)這一目標(biāo)臊诊,只要匯總統(tǒng)計(jì)每個(gè)球員的三雙數(shù)據(jù)取平均值就可以了,不過在此之前斜脂,還需要對數(shù)據(jù)進(jìn)行一番篩選抓艳,我們都知道,只有樣本數(shù)量較大的時(shí)候秽褒,數(shù)據(jù)平均值才不至于太夸張壶硅,這里我將篩選拿到超過 10 次三雙的球員進(jìn)行比較:
player_tribles 就是我們想要的每位球員三雙場次的平均數(shù)據(jù),輸入 player_tribles.head(10) 可得到以下的表格:
根據(jù)平均得分?jǐn)?shù)值大小排名销斟,抽取一部分進(jìn)行比較:
1. 詹姆斯·哈登的三雙場次平均數(shù)據(jù)在得分庐椒、籃板、助攻上居然稍壓邁克爾·哪里都有我·喬丹蚂踊,可以通過 df3[df3['player']=='James Harden'].sort_values(by='pts',ascending=False) 查看哈登所有的三雙場次數(shù)據(jù)约谈,本賽常規(guī)賽居然打出了兩次驚世駭俗的 50 分三雙,還有 5 次 40 分三雙,所以三雙場次平均得分被拉上也不奇怪了棱诱;
2. 威少和詹姆斯兩位「全能戰(zhàn)士」的比較泼橘,威少在得分、籃板迈勋、助攻上穩(wěn)壓詹姆斯炬灭,但籃球從來不是一個(gè)數(shù)據(jù)游戲,熟悉 NBA 的朋友應(yīng)該知道靡菇,有些球員對比賽的影響并不會(huì)體現(xiàn)在數(shù)據(jù)上重归;
3. 一生宿敵,海軍上將與大夢厦凤,兩人的場均數(shù)據(jù)都沒有達(dá)到三雙鼻吮,是什么原因呢,通過 df3[df3['player']=='...'] 查詢较鼓,原來他們都曾得過不同類型的三雙椎木,包括「得分+籃板+助攻」類型和「得分+籃板+蓋帽」類型,所以數(shù)據(jù)平均下來沒有達(dá)到三雙博烂,但也側(cè)面說面他們的全面身手香椎。(P.S. 巧合的是,兩人都得到四雙)
4. 大家都熟悉的科比禽篱,共拿到 21 次三雙士鸥,24.48 的平均得分似乎并不符合歷史級得分高手的「人設(shè)」,要進(jìn)一步探究的話谆级,可以補(bǔ)充一下出手次數(shù)和命中率的數(shù)據(jù)烤礁,分析是他拿三雙的場次,到底是出手意愿不強(qiáng)肥照,還是命中率被限制了脚仔。
同樣通過 player_tribles.tail(10) 也可以得出:
再來看看三雙場次平均得分較低的十位球員的數(shù)據(jù):
1. 之前因?yàn)榭辞蛲恚∠笾械慕?jīng)濟(jì)型三雙秤咭铮客基德鲤脏,實(shí)際上他在拿到三雙的比賽中平均得分不算低,可能是被生涯后期的數(shù)據(jù)拖累吕朵。而三雙拿得最「經(jīng)濟(jì)」的當(dāng)屬被我 Darrell Walker猎醇,曾是 93 公牛的一員,職業(yè)生涯最佳的賽季數(shù)據(jù)為 9.5+8.8+8(1989-90賽季 華盛頓子彈隊(duì))努溃。
2. 現(xiàn)役球員中硫嘶,三雙平均數(shù)據(jù)最經(jīng)濟(jì)的是追夢格林,平均得分居然沒有「真拒投」隆多高…通過 df3[df3['player']=='Draymond Green'] 查了一下梧税,他居然在這賽季拿過一次「籃板+助攻+搶斷」的詭異三雙沦疾。
結(jié)語
至此称近,文章標(biāo)題提到的問題相信已經(jīng)有答案了,由于現(xiàn)有的數(shù)據(jù)已經(jīng)能得出結(jié)論了哮塞,就不加入可視化的操作了(也考慮到篇幅問題)刨秆。帶著分析目的,從數(shù)據(jù)抓取到數(shù)據(jù)清洗忆畅,再到數(shù)據(jù)分析(甚至可視化)衡未,可以算是一個(gè)比較完整的分析過程了。每一個(gè)步驟產(chǎn)出不同的結(jié)果家凯,一步一步逼近「真相」眠屎。
當(dāng)然,本例子的數(shù)據(jù)量不大肆饶,數(shù)據(jù)清洗,數(shù)據(jù)分析以及可視化岖常,都是可以通過其他工具(比如 Excel驯镊,BI)完成的,但如果數(shù)據(jù)量較大時(shí)竭鞍,采用 Pandas 的優(yōu)勢便會(huì)顯示出來板惑。
文章里的代碼都是現(xiàn)學(xué)現(xiàn)賣的,未必是最優(yōu)的解決方案偎快,遇到問題冯乘,查查官方文檔就對了 :-)