前言
1. 這篇數據分析案例,我做了個? 視頻版本 ?,對代碼做了解讀,講了運行的注意事項和一些有的沒的,供需。對于視頻制作還不是很有經驗,多包涵。(視頻里有彩蛋)
2. 本文在案例的代碼寫完后,我把它發在了? 虎撲 ?上。結果,被推薦上了首頁,? 25萬多次瀏覽,近800回復 ?……感謝各位JRs賞臉!
3. 獲取原圖、更多球員生成的結果及完整代碼,請在公眾號“? Crossin的編程教室 ?”內回復關鍵字:? nba
--------------------
NBA 2018-19 賽季已經落下帷幕,猛龍擊敗勇士,成為新科冠軍球隊。
我想,不如來做個? NBA 相關的數據分析 ?案例好了。實際上,數據分析團隊對于現在的 NBA 球隊已經算是標配了,無論是在球員選擇還是戰術制定上都起著重要的作用。當下整個聯盟越來越盛行的“? 魔球化 ?”打法,其實也正是基于數據分析的產物。
于是,我們就借助? 官方數據 ?和? Python 的繪圖函數 ?,來看一看? 不同的球員都是在什么位置出手投籃的 ?。
0. 效果展示
照例先看結果,每個點是一次投籃,? 藍色點是投中,紅色點是未中 ?。挑幾個有特點的:
哈登 ?,魔球得很明顯了,長兩分這種低效率的事絕對不干
西蒙斯 ?,古典中鋒
德拉贊 ?,中投小王子
字母哥 ?,籃下都給你扣糊了!
庫里 ?,這個得放全場……
科比 ?,生涯累計圖,全方位無死角,包括籃板后負角度
下面來看具體步驟,我們以剛剛獲得本賽季冠軍戒指的林書豪作為例子。
1. 獲取數據
NBA 有一個官方統計網站:? http://?stats.nba.com? ,上面有各種數據,可以說是一個寶藏了。
從網頁上,我沒有找到這次所需的數據。但通過一番搜索,我找到了網站的開放接口 API。相關的接口和文檔你可以從這個項目里查看:
nba_py - http:// stats.nba.com API for python
https://?github.com/seemethere/n?ba_py/
通過以下接口,我們可以獲取某個球員在指定賽季的投籃詳細數據:
https://?stats.nba.com/stats/sho?tchartdetail?CFID=33&CFPARAMS=2018-19&ContextFilter=&ContextMeasure=FGA&DateFrom=&DateTo=&GameID=&GameSegment=&LastNGames=0&LeagueID=00&Location=&MeasureType=Base&Month=0&OpponentTeamID=0&Outcome=&PaceAdjust=N&PerMode=PerGame&Period=0&PlayerID=201935&PlusMinus=N&Position=&Rank=N&RookieYear=&Season=2018-19&SeasonSegment=&SeasonType=Regular+Season&TeamID=0&VsConference=&VsDivision=&mode=Advanced&showDetails=0&showShots=1&showZones=0&PlayerPosition=
其中參數? PlayerID ?是查詢球員的 ID,這個 ID 可以通過在網頁上搜索球員姓名,從對應的 URL 中獲取。比如林書豪就是? 202391
https://?stats.nba.com/player/20?2391/
鏈接中的兩處? 2018-19 ?是賽季參數,你可以改成其他賽季,不過我試過不能太早,大約 96 年往前就沒數據了,而且早期數據精度要差些。
其他參數可以不用管。
用?requests?庫可輕松獲取結果(需加上 headers):
response = requests.get(url, headers=headers, timeout=5)
?
2. 解析數據
返回的數據是? JSON ?格式,用? pandas ?轉成? DataFrame ?格式,方便后續處理:
data = response.json()
# 獲取列名即每項投球數據的意思
headers = data['resultSets'][0]['headers']
# 獲取投球的相關數據
shots = data['resultSets'][0]['rowSet']
# 轉 DataFrame
shot_df = pd.DataFrame(shots, columns=headers)
PYthon學習企鵝裙:88198-2657 領取python自動化編程資料教程
我們關心的數據就是? LOC_X ?、? LOC_Y ?(出手位置)和? SHOT_MADE_FLAG ?(是否投中)這三列。
3. 繪制投籃點
使用? matplotlib ?庫的散點圖繪制? scatter ?方法就可以把投籃點畫出來,這個我們之前的各種案例里也用過不少次了:
made = shot_df[shot_df['SHOT_MADE_FLAG']==1]
miss = shot_df[shot_df['SHOT_MADE_FLAG']==0]
plt.scatter(miss.LOC_X, miss.LOC_Y, color='r', marker='.', alpha=0.3)
plt.scatter(made.LOC_X, made.LOC_Y, color='b', marker='.', alpha=0.3)
PYthon學習企鵝裙:88198-2657 領取python自動化編程資料教程
我們通過參數設定點的大小和透明度,讓顯示更清楚。
4. 繪制球場
投籃點畫出來了,不過只是這樣不夠直觀。我們再來加個球場的圖。
這個是通過? matplotlib ?里的? Circle ?、? Rectangle ?、? Arc ?等方法拼出來的,沒啥特別的技術,但代碼比較繁瑣,這邊就不貼了。(只要你愿意,甚至可以用它畫出小豬佩奇)
5. 添加頭像
最后,再給數據圖加上一個頭像,讓它看起來更完整。頭像地址:
https://?stats.nba.com/media/pla?yers/230x185/202391.png
或者
https://?ak-static.cms.nba.com/w?p-content/uploads/headshots/nba/latest/260x190/202391.png
文件名依然是球員的 ID,但這個地址并不是對所有球員有效,可做下異常處理。
pic = urllib.request.urlretrieve("http://stats.nba.com/media/players/230x185/202391.png")
# imread 讀取的圖像可以被 matplotlib 繪制
head_pic = plt.imread(pic[0])
# 將球員圖片放置于右上角,并設置縮小等級以配合整個圖片
img = OffsetImage(head_pic, zoom=0.6)
# (x, y) 控制將球員放在你想要放的位置
img.set_offset((540,640))
# 添加球員圖片
fig.gca().add_artist(img)
如果在你的電腦上位置不對,記得修改下? offset ?的值(不同系統,甚至不同編譯器都可能存在差異)。
最終效果:
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元

