無數據的分析不過一場嘴炮。本篇內容爲科賽網用戶AK_47基於科賽網明星數據集《NBA數據集》,進行的全面理性分析。30年最強奪冠陣容誰說了算,數據裏見分曉。javascript
NBA數據集:NBA歷史各賽季常規及季後賽球員、球隊及教練綜合數據,另附各球員的賽季薪金數據(NBA歷史統計緣由,僅存1985-86賽季以後的單場比賽球員數據。
先來看看科賽提供了哪些數據集:java
ls ../input/NBAdata/
複製代碼
advanced_basic.csv coach_playoff.csv player_salary.csv team_playoff.csv
advanced_shooting.csv coach_season.csv player_season.csv team_season.csv
avg.csv player_playoff.csv single.csv tot.csv複製代碼
既然是找尋史上最XX總冠軍,那麼 team_season.csv 和 team_playoff.csv這兩個數據集即是咱們關注的重點。python
# 導入經常使用的庫
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
# R語言中的ggplot畫圖很漂亮,咱們一樣能夠調用參數,在Python實現相似風格的可視化
from matplotlib import style
style.use('ggplot')
# 設置warnings
import warnings
warnings.filterwarnings('ignore')
複製代碼
# 導入數據
T_season = pd.read_csv('../input/NBAdata/team_season.csv')
T_playoff = pd.read_csv('../input/NBAdata/team_playoff.csv')複製代碼
看一眼球隊季後賽表現T_playoff.csv這個數據集長什麼樣bash
T_playoff.head()複製代碼
5 rows × 23 columnsapp
裏面有哪些columns?
ide
T_playoff.columns複製代碼
Index(['球隊', '時間', '結果', '主/客場', '比分', '投籃', '命中', '出手', '三分', '三分命中', '三分出手',
'罰球', '罰球命中', '罰球出手', '籃板', '前場', '後場', '助攻', '搶斷', '蓋帽', '失誤', '犯規',
'得分'],
dtype='object')複製代碼
對於球隊常規賽數據集T_season.csv也是一樣的處理方法:優化
T_season.head()複製代碼
5 rows × 23 columns
ui
T_season.columns複製代碼
Index(['球隊', '時間', '結果', '主/客場', '比分', '投籃', '命中', '出手', '三分', '三分命中', '三分出手',
'罰球', '罰球命中', '罰球出手', '籃板', '前場', '後場', '助攻', '搶斷', '蓋帽', '失誤', '犯規',
'得分'],
dtype='object')複製代碼
以上咱們大體瞭解了數據集涵蓋的字段和內容,下面開始找尋史上最XX總冠軍的征程。
spa
既然目標是找尋史上最XX總冠軍,那麼咱們先要找到歷年的奪冠球隊,再進行分析。3d
# 添加對手字段
T_playoff['對手'] = T_playoff['比分'].apply(lambda x: x[0:3])
T_season['對手'] = T_season['比分'].apply(lambda x: x[0:3])
#增長賽季字段,整理年份
T_playoff['賽季'] = T_playoff['時間'].str.extract('([0-9]{4})').astype('int')
#搬來代碼,整理冠軍及年份
win_dic={}
for i in T_playoff['球隊'].unique():
win_dic[i]={}
for i in range(1986,2017):
for j in T_playoff['球隊'].unique():
win_dic[j][i]=len(T_playoff[T_playoff.球隊==j][T_playoff.賽季==i][T_playoff.結果=='W'].index)
win_count=pd.DataFrame(win_dic)
winner={}
for i in win_count.index:
winner[i]=win_count.loc[i].sort_values(ascending=False).keys()[0]
winner=pd.Series(winner)
T_playoff['時間'] = pd.to_datetime(T_playoff['時間'])
複製代碼
總冠軍歸屬整理以下表:
原來近三十年奪冠也就是這幾支球隊輪流坐莊,那麼這些球隊瓜分總冠軍的次數如何,請看下圖分解:
plt.figure(figsize=(12,7))
plt.axes(axisbg='#F5F5F5') #設置一個好看的背景色
winner.value_counts().plot(kind='bar',color='blue')
plt.xlabel('球隊')
plt.ylabel('總冠軍個數')
plt.title('圖1 NBA總冠軍如何被瓜分')
plt.show()複製代碼
不看不知道,一看嚇一跳:
好戲就此開始,咱們先從各年總冠軍的常規賽講起。
# 找到總冠軍在奪冠賽季的常規賽和季後賽數據 以及對手的數據
start_time = [str(i)+'-10-01' for i in range(1985,2016)]
end_time = [str(i)+'-07-01' for i in range(1986,2017)]
Name = [winner[i] for i in range(1986,2017)]
Champ_season = [[] for i in range(0,31)]
Champ_playoff = [[] for i in range(0,31)]
Champ_opp_season =[[] for i in range(0,31)]
Champ_opp_playoff = [[] for i in range(0,31)]
for i in range(0,31):
Champ_playoff[i] = T_playoff[(T_playoff['球隊']==Name[i])&
(T_playoff['時間']>start_time[i])&
(T_playoff['時間']<end_time[i])]
Champ_opp_playoff[i] = T_playoff[(T_playoff['對手']==Name[i])&
(T_playoff['時間']>start_time[i])&
(T_playoff['時間']<end_time[i])]
Champ_season[i] = T_season[(T_season['球隊']==Name[i])&
(T_season['時間']>start_time[i])&
(T_season['時間']<end_time[i])]
Champ_opp_season[i] = T_season[(T_season['對手']==Name[i])&
(T_season['時間']>start_time[i])&
(T_season['時間']<end_time[i])]
複製代碼
def get_wininfo(data):
Wscore = []
Wrate = []
for i in range(0,31):
temp = data[i]
Wrate.append(round(len(temp[temp['結果']=='W'])/len(temp),2))
Wscore.append(temp['得分'].mean())
return Wscore, Wrate
複製代碼
def get_Rtg(Champ,Opp):
DRtg = []
ORtg = []
for i in range(0,31):
temp1 = Champ[i]
temp2 = Opp[i]
DRtg.append((temp1['得分'].mean()*100)/(temp1['出手'].mean()-temp1['前場'].mean()+temp1['失誤'].mean()+temp1['罰球出手'].mean()*0.44))
ORtg.append((temp2['得分'].mean()*100)/(temp2['出手'].mean()-temp2['前場'].mean()+temp2['失誤'].mean()+temp2['罰球出手'].mean()*0.44))
return DRtg,ORtg
複製代碼
這一部分咱們考察的點主要有:
進攻效率值: 得分 X 100/(出手次數-前場籃板+本身失誤+罰球出手 X 0.44)
防守效率值: 對手得分 X 100/(對手的出手次數-對手的前場籃板+對手的失誤+對手的罰球出手 X 0.44)
常規賽勝率 v.s 場均得分
在下圖中咱們統計了歷年總冠軍的常規賽場均得分與勝率,其中勝率乘了係數100,這樣放在了一個座標系中,用藍色表示。
w_score = get_wininfo(Champ_season)[0]
w_rate = get_wininfo(Champ_season)[1]
size = [i*100 for i in w_rate]
idx = range(0,31)
tick = [str(winner.index[i]) + '-' + str(winner[i+1986]) for i in range(0,31)]
plt.figure(1,figsize=(12,6))
plt.axes(axisbg='#F5F5F5')
plt.scatter(idx,w_score,label='場均得分')
plt.plot(idx,w_score,linestyle='--',linewidth=1,color='blue')
plt.scatter(idx,size,label='勝率')
plt.plot(idx,size,linestyle='--',linewidth=1,color='black')
plt.setp(plt.xticks(idx,tick)[1],rotation=90)
plt.title('圖2 常規賽 - 場均得分 vs 勝率')
plt.xlabel('年份-冠軍')
plt.legend(bbox_to_anchor=(1.13,1))
plt.show()
複製代碼
不看不知道,一看嚇一跳:
三分球統計
咱們統計了各個總冠軍的三分出手次數、命中次數以及命中率(命中率乘了係數100,便於展現)
T_season_3pt = [Champ_season[i].三分出手.mean() for i in range(0,31)]
T_season_3p = [Champ_season[i].三分命中.mean() for i in range(0,31)]
rate = [100 * T_season_3p[i]/T_season_3pt[i] for i in range(0,31)]
# Twenty = [20 for i in range(0,31)]
plt.figure(1,figsize=(12,6))
plt.axes(axisbg='#F5F5F5')
plt.bar(idx,T_season_3pt,label='場均出手')
plt.bar(idx,T_season_3p,label='場均命中數')
plt.scatter(idx,rate,label='命中率')
plt.plot(idx,rate,linewidth=0.5,color='black',linestyle='--')
plt.legend(bbox_to_anchor=(1,1))
plt.setp(plt.xticks(idx,tick)[1],rotation=90)
plt.title('圖3 常規賽 - 三分統計')
plt.xlabel('年份-冠軍')
plt.show()
複製代碼
籃板統計
總冠軍們在常規賽的場均進攻籃板,防守籃板,總籃板分別進行了歸類
T_season_dreb = [Champ_season[i].後場.mean() for i in range(0,31)]
T_season_oreb = [Champ_season[i].前場.mean() for i in range(0,31)]
T_season_reb = [Champ_season[i].籃板.mean() for i in range(0,31)]
dreb_mean = [np.array(T_season_dreb).mean() for i in range(0,31)]
oreb_mean = [np.array(T_season_oreb).mean() for i in range(0,31)]
reb_mean = [np.array(T_season_reb).mean() for i in range(0,31)]
plt.figure(1,figsize=(12,6))
plt.axes(axisbg='#F5F5F5')
plt.scatter(idx,T_season_oreb,label='進攻籃板')
plt.scatter(idx,T_season_dreb,label='防守籃板')
plt.scatter(idx,T_season_reb,label='總籃板')
plt.plot(idx,T_season_oreb, color='green', linestyle='-', linewidth=0.5)
plt.plot(idx,T_season_dreb, color='green', linestyle='-', linewidth=0.5)
plt.plot(idx,T_season_reb, color='green', linestyle='-', linewidth=0.5)
plt.plot(idx,dreb_mean, color='black', linestyle='--', linewidth=1,label='平均值')
plt.plot(idx,oreb_mean, color='black', linestyle='--', linewidth=1)
plt.plot(idx,reb_mean, color='black', linestyle='--', linewidth=1)
plt.setp(plt.xticks(idx,tick)[1],rotation=90)
plt.title('圖4 常規賽 - 籃板表現')
plt.ylabel('場均籃板數')
plt.xlabel('年份-冠軍')
plt.legend(bbox_to_anchor=(1,1))
plt.show()複製代碼
助攻統計
總冠軍們在常規賽的場均助攻表現以下:
T_season_assist = [Champ_season[i].助攻.mean() for i in range(0,31)]
ast_mean = [np.array(T_season_assist).mean() for i in range(0,31)]
plt.figure(1,figsize=(12,6))
plt.axes(axisbg='#F5F5F5')
plt.scatter(idx,T_season_assist,label='場均助攻數')
plt.plot(idx,T_season_assist,linestyle='-',linewidth=0.5,color='black')
plt.plot(idx,ast_mean,color='blue', linestyle='--', linewidth=1,label='平均值')
plt.title('圖5 常規賽 - 助攻表現')
plt.ylabel('場均助攻數')
plt.xlabel(å'年份-冠軍')
plt.ylim(17)
plt.setp(plt.xticks(idx,tick)[1],rotation=90)
plt.legend(bbox_to_anchor=(1.15,1))
plt.show()複製代碼
常規賽進攻與防守效率值
Dseason = get_Rtg(Champ_season,Champ_opp_season)[0]
Oseason = get_Rtg(Champ_season,Champ_opp_season)[1]
plt.figure(1,figsize=(12,6))
plt.axes(axisbg='#F5F5F5')
plt.scatter(idx,Dseason,label='進攻效率值')
plt.scatter(idx,Oseason,label='防守效率值')
Dseason_mean = [np.array(Dseason).mean() for i in range(0,31)]
Oseason_mean = [np.array(Oseason).mean() for i in range(0,31)]
plt.plot(idx,Dseason,linestyle='-',linewidth=0.5)
plt.plot(idx,Oseason,linestyle='-',linewidth=0.5)
plt.plot(idx,Dseason_mean, color='black', linestyle='--', linewidth=1,label='平均值')
plt.plot(idx,Oseason_mean, color='black', linestyle='--', linewidth=1)
plt.setp(plt.xticks(idx,tick)[1],rotation=90)
plt.legend(bbox_to_anchor=(1.14,1))
plt.title('圖6 常規賽 - 進攻/防守效率值')
plt.xlabel('年份-冠軍')
plt.ylabel('效率值')
plt.show()複製代碼
同常規賽部分,咱們考察的點依舊集中在常規賽勝率 v.s 場均得分,三分球,籃板,助攻,進攻效率值和防守效率值這幾個指標上面。
得分高於對手,才能贏得比賽。
T_playoff_mean = [Champ_playoff[i].得分.mean() for i in range(0,31)]
mean = [np.array(T_playoff_mean).mean() for i in range(0,31)]
plt.figure(figsize=(12,6))
plt.axes(axisbg='#F5F5F5')
plt.scatter(idx,T_playoff_mean)
plt.plot(idx,T_playoff_mean,linestyle='--', linewidth=0.5,label='場均得分')
plt.plot(idx,mean, color='blue', linestyle='--', linewidth=1,label='平均值')
plt.setp(plt.xticks(idx,tick)[1],rotation=90)
plt.title('圖7 季後賽 - 場均得分')
plt.xlabel('年份-冠軍')
plt.legend(bbox_to_anchor=(1,1))
plt.ylim(85)
plt.show()
複製代碼
論得分表現:
無兄弟,不籃球;無助攻,可貴分。
T_playoff_assist = [Champ_playoff[i].助攻.mean() for i in range(0,31)]
ast_mean = [np.array(T_playoff_assist).mean() for i in range(0,31)]
plt.figure(1,figsize=(12,6))
plt.axes(axisbg='#F5F5F5')
plt.scatter(idx,T_playoff_assist)
plt.plot(idx,T_playoff_assist,linestyle='-',linewidth=0.5,color='black')
plt.plot(idx,ast_mean,color='blue', linestyle='--', linewidth=1,label='平均值')
plt.title('圖8 季後賽 - 助攻表現')
plt.ylabel('場均助攻數')
plt.xlabel('年份-冠軍')
plt.ylim(17)
plt.setp(plt.xticks(idx,tick)[1],rotation=90)
plt.legend(bbox_to_anchor=(1,1))
plt.show()複製代碼
論助攻表現:
籃板籃板籃板,重要的事說三遍。
T_playoff_dreb = [Champ_playoff[i].後場.mean() for i in range(0,31)]
T_playoff_oreb = [Champ_playoff[i].前場.mean() for i in range(0,31)]
T_reb = [Champ_playoff[i].籃板.mean() for i in range(0,31)]
dreb_mean = [np.array(T_playoff_dreb).mean() for i in range(0,31)]
oreb_mean = [np.array(T_playoff_oreb).mean() for i in range(0,31)]
reb_mean = [np.array(T_reb).mean() for i in range(0,31)]
plt.figure(1,figsize=(12,6))
plt.axes(axisbg='#F5F5F5')
plt.scatter(idx,T_playoff_oreb,label='進攻籃板')
plt.scatter(idx,T_playoff_dreb,label='防守籃板')
plt.scatter(idx,T_reb,label='總籃板')
plt.plot(idx,T_playoff_oreb, color='green', linestyle='-', linewidth=0.5)
plt.plot(idx,T_playoff_dreb, color='green', linestyle='-', linewidth=0.5)
plt.plot(idx,T_reb, color='green', linestyle='-', linewidth=0.5)
plt.plot(idx,dreb_mean, color='black', linestyle='--', linewidth=1,label='平均值')
plt.plot(idx,oreb_mean, color='black', linestyle='--', linewidth=1)
plt.plot(idx,reb_mean, color='black', linestyle='--', linewidth=1)
plt.setp(plt.xticks(idx,tick)[1],rotation=90)
plt.title('圖9 季後賽 - 籃板表現')
plt.ylabel('場均籃板數')
plt.xlabel('年份-冠軍')
plt.legend(bbox_to_anchor=(1,1))
plt.show()複製代碼
論籃板能力:
他強任他強,三分我最狂。
T_playoff_3pt = [Champ_playoff[i].三分出手.mean() for i in range(0,31)]
T_playoff_3p = [Champ_playoff[i].三分命中.mean() for i in range(0,31)]
rate = [100 * T_playoff_3p[i]/T_playoff_3pt[i] for i in range(0,31)]
rate_mean = [np.array(rate).mean() for i in range(0,31)]
plt.figure(1,figsize=(12,6))
plt.axes(axisbg='#F5F5F5')
plt.bar(idx,T_playoff_3pt,label='場均出手')
plt.bar(idx,T_playoff_3p,label='場均命中數')
plt.scatter(idx,rate,label='命中率')
plt.plot(idx,rate,linewidth=0.5,color='black',linestyle='--',label='平均值')
plt.plot(idx,rate_mean,linewidth=1,color='black',linestyle='--')
plt.setp(plt.xticks(idx,tick)[1],rotation=90)
plt.legend(bbox_to_anchor=(1,1))
plt.title('圖10 季後賽 - 三分表現')
plt.show()
複製代碼
論三分球表現
高階數據纔是實力的體現:季後賽進攻&防守效率值
Dseason = get_Rtg(Champ_playoff,Champ_opp_playoff)[0]
Oseason = get_Rtg(Champ_playoff,Champ_opp_playoff)[1]
plt.figure(1,figsize=(12,6))
plt.axes(axisbg='#F5F5F5')
plt.scatter(idx,Dseason,label='進攻效率值')
plt.scatter(idx,Oseason,label='防守效率值')
plt.plot(idx,Dseason,linestyle='-',linewidth=0.5)
plt.plot(idx,Oseason,linestyle='-',linewidth=0.5)
Dseason_mean = [np.array(Dseason).mean() for i in range(0,31)]
Oseason_mean = [np.array(Oseason).mean() for i in range(0,31)]
plt.plot(idx,Dseason_mean, color='black', linestyle='--', linewidth=1,label='平均值')
plt.plot(idx,Oseason_mean, color='black', linestyle='--', linewidth=1)
plt.setp(plt.xticks(idx,tick)[1],rotation=90)
plt.title('圖11 季後賽 - 進攻/防守效率值')
plt.ylabel('效率值')
plt.xlabel('年份-冠軍')
plt.legend(bbox_to_anchor=(1,1))
plt.show()
複製代碼
關鍵詞:團隊籃球 & 三分球
若是你是一名NBA老球迷,你必定聽過「永遠不要低估了一顆總冠軍的心」這句話。屌絲逆襲的故事也在NBA中發生着,because it is where amazing happens. 從未有哪隻球隊像1995年的休斯頓火箭隊同樣,在本身的衛冕道路上走得如此艱難。常規賽階段,勝率不足六成,進攻端低迷,防守端被爆,一路跌跌撞撞,以西部第六的身份進入季後賽。最終依靠團隊籃球與三分球贏下德州小強的名號,帶走了總冠軍。
團隊籃球:1995年的火箭在當年季後賽場均送出25次以上助攻,後來從未有球隊在季後賽中作到過這一點
三分球: 對!你沒看錯,火箭在那個年代就在投三分球!1995年的火箭在季候賽有着媲美如今勇士和騎士的三分球命中率,而且三分出手次數在那個年代也是前無古人
關鍵詞:助攻 + 籃板 + 得分 並駕齊驅
這是一個大鳥博德(Larry Bird)與魔術師相互爭霸的年代,向偉大體敬!
關鍵詞:三分如雨下
2015年的金州勇士可謂是一隻現象級的球隊,在常規賽階段就展示了震古爍今的三分球功力,場均至少10記三分+40%命中率的穩定輸出爲他們早早鎖定了季後賽席位。在季後賽中,勇士也可謂用三分球技能大殺四方,將場均三分出手次數提高到了30+而命中率微弱下降。史上最佳三分總冠軍的稱號,實至名歸。
關鍵詞:進攻是最好的防守
這是進攻籃球最好的時代,這是魔術師的show time。這一年的洛杉磯湖人(LAL)常規賽階段便在進攻端展現出極強的破壞力,八成勝率進入季後賽,以後更是以場均120+的歷史第一高分奪得總冠軍,開啓了湖人在那個時代的兩連冠。
關鍵詞:防守是最好的進攻
論最佳防守總冠軍,若是活塞說本身是第二,馬刺絕對不敢說本身是第一。2004年的底特律活塞被稱爲「壞孩子」。這羣「壞孩子」們在常規賽階段就展示了本身對進攻的「厭惡」:場均不到90分也是沒誰了。到了季後賽,這羣「壞孩子」們更是將防守和進攻演繹到了極致:進攻效率值史上最低,而防守效率倒是史上最佳。原來他們把進攻的功夫所有拿去防守了。This is where amazing happens,向這羣「壞孩子」們致敬!
關鍵詞:完美
若是非要找出史上最強總冠軍的話,1996年的芝加哥公牛(CHI)當之無愧。來,數聽說話:
from IPython.display import HTML
HTML('''<script> code_show=true; function code_toggle() { if (code_show){ $('div.input').hide(); } else { $('div.input').show(); } code_show = !code_show } $( document ).ready(code_toggle); </script> 有球迷的地方就有江湖,有江湖的地方就會有懂球帝和數據分析老司機。爲了更好的閱讀體驗,源代碼已經設置隱藏。若有須要,請看這裏<a href="javascript:code_toggle()">這裏</a>.''')
複製代碼
有球迷的地方就有江湖,有江湖的地方就會有懂球帝和數據分析老司機。
本做品完整源代碼可直接登陸科賽,在「項目」欄目查看,並能使用K-Lab的「Fork」鍵功能在源代碼基礎上再優化,生成本身的分析做品。