我从小学就比较喜欢篮球运动,特别对NBA也比较关注,现在学习了Python爬虫知识了,现在用用Python分析和詹姆斯和伦纳德在NBA职业生涯,这应该是一件非常有趣的事情。
拥有最强大脑、最独特视角的数据分析狂热者,将针对体育、影视、音乐、财经四大领域内最生活的话题,开展有趣又烧脑的数据分析探索之旅。
首期我们从NBA话题切入,在官网发布了超全的NBA数据集(所有球员&球队的常规赛、季后赛,教练执教、球员各赛季薪金的数据),N位网友在线根据自己的兴趣,发布了数据分析项目,切入点很多样,也很有意思。如,王者荣耀 — NBA数据分析 [增加梅西评分模型]、乔科詹库之全方位分析……
这里PO其中一份原创作品@大野人007 ,感兴趣的朋友也可直接登录kesci.com,Fork过来在K-Lab上开展个人分析。附:原贴链接。
NBA数据集获取路径:登录kesci.com-点击「K-Lab」-找到「NBA数据集」
关于K-Lab。
K-Lab是科赛网重点打造的在线数据分析协作平台。它涵盖了Python、R等主流语言,完成了90%以上数据分析&挖掘相关库的部署(如题主所提到的pandas, numpy, matplotlib),免去了本地搭建环境的烦恼,实现了即刻线上动手做分析项目。
伦纳德和詹姆斯两人的差距体现在哪?
1)数据维度
球员基本信息(姓名/所属球队/球员年龄)
比赛信息(参赛球队/场地/比赛分差)
球员表现(比赛时间/得分效率/得分类型)
2)数据处理
!ls ../input/NBAdata/
# 导入必要的包.
# 导入必要的包.import pandas as pdimport matplotlib.pyplot as pltimport seaborn as snsimport warningsimport numpy as npimport pylab%matplotlib inlinewarnings.filterwarnings('ignore')
读取球员场均数据
player_avg = pd.read_csv('avg.csv') player_avg.head()
展示要分析的数据
pd.set_option('display.max_columns',30)player_avg[(player_avg['姓名'] == 'Kawhi Leonard') & (player_avg['赛季'] == '16--17')]
pd.set_option('display.max_columns',50)L_1617_avg = player_avg[(player_avg['姓名'] == 'LeBron James') & (player_avg['赛季'] == '16--17')]L_1617_avg
对比分析及数据可视化
class Radar(object): n = 1 angles =None def __init__(self, fig, titles, labels, rect=None): if rect is None: rect = [0.05, 0.05, 0.95, 0.95] self.n = len(titles) self.angles = np.arange(90, 90+360, 360.0/self.n) self.axes = [fig.add_axes(rect, projection="polar", label="axes%d" % i) for i in range(self.n)] self.ax = self.axes[0] self.ax.set_thetagrids(self.angles, labels=titles, fontsize=14) for ax in self.axes[1:]: ax.patch.set_visible(False) ax.grid("off") ax.xaxis.set_visible(False) for ax, angle, label in zip(self.axes, self.angles, labels): ax.set_rgrids(range(1, 6), angle=angle, labels=label) ax.spines["polar"].set_visible(False) ax.set_ylim(0, 5) def angle(self, values, *args, **kw): return np.deg2rad(np.r_[self.angles]),np.r_[values],values def plot(self, values, *args, **kw): angle = np.deg2rad(np.r_[self.angles, self.angles[0]]) values = np.r_[values, values[0]] self.ax.plot(angle, values, *args, **kw)titles_ = ['score','shoot','rebound','assist','three','penalty','steal','block']titles = ['得分','投篮','篮板','助攻','三分','罚球','抢断','盖帽']# titles = list("ABCDE")
我们发现:
赢
詹姆斯突破得分能力更强。两人出手次数差不多,詹命中率高了5个百分点左右
詹姆斯的组织能力更强。詹助攻数场均多5.2个
詹姆斯的篮板能力稍胜一筹。相同出场次数,詹均多2.8个篮板球
输
伦纳德的投篮能力更好。罚球能力一样,但詹命中率差了20个百分点
伦纳德抢断能力更加出色。伦的场均抢断数要高0.5个
以上分析较宏观,不能反映事物的本质。下面从微观角度(每场比赛的数据)进行分析。
角度1:基于篮板球
# data_statistics函数主要是方便categoricl型的数据的统计显示,方便后续绘图使用def data_statistics(Kawhi_season1617, Lebron_season1617, name): Kawhi_season1617_ = pd.DataFrame(Kawhi_season1617.groupby(name)['球员'].count()) Kawhi_season1617_.columns = ['K_次数'] Kawhi_season1617_.reset_index(inplace=True) Lebron_season1617_ = pd.DataFrame(Lebron_season1617.groupby(name)['球员'].count()) Lebron_season1617_.columns = ['L_次数'] Lebron_season1617_.reset_index(inplace=True) data = pd.merge(Lebron_season1617_,Kawhi_season1617_,on = name , how ='outer') data = data.fillna(0) data = data.sort_values(name) return data
用seaborn做柱状图可视化
rebounds['K_次数'] = rebounds['K_次数'] * -1plt.figure(figsize=[16,6])sns.barplot(x = '篮板', y = 'L_次数', data = rebounds, color='red')sns.barplot(x = '篮板',y = 'K_次数', data = rebounds, color ='blue')
红色:詹姆斯,蓝色:伦纳德
横轴:篮板数,纵轴:发生次数
可以看出:
詹姆斯的篮板球能力远超伦纳德。
詹姆斯在数据层面比伦纳德高个档次。
角度2:基于得分
score['K_次数'] = score['K_次数'] * -1plt.figure(figsize=[16,6])sns.barplot(x = '得分', y = 'L_次数', data = score, color='red')sns.barplot(x = '得分',y = 'K_次数', data = score, color ='blue')
横轴:得分数,纵轴:发生次数
用seaborn做violin图可视化
plt.figure(figsize= [12,5])total = pd.concat([Kawhi_season1617,Lebron_season1617])total['Is_Kawhi'] = 0total.loc[total['球员'] == 'Kawhi Leonard','Is_Kawhi'] = 1total['A'] = 0sns.violinplot(x= 'A' , y = '得分', hue = 'Is_Kawhi', data = total, split=True)
绿色:伦纳德,蓝色:詹姆斯
詹姆斯的得分较稳,伦纳德的得分分布更广,但总体两人差异不大。因此将分数划为几档,再来看:
0 - 15分 定为档1
15 - 19 定为档2
20 - 24 定为档3
25 - 29 定为档4
30 - 定为档5
横轴:得分层次,纵轴:发生次数
詹姆斯的得分更稳定,基本在25分附近。
伦纳德的得分分布范围更广,得分的爆发力更好。从档5来看,伦纳德更占优势,不过这也从侧面反映了一点外线投篮好的职业选手的优势。手感来了分分钟爆表,而手感差的话也会出现很多档1档2的情况。
角度3:基于投篮命中率
shoot = data_statistics(Kawhi_season1617, Lebron_season1617, '投篮')shoot# sns.distplot(Kawhi_season1617.groupby('得分')['球员'].count(),color='b')# sns.distplot(Lebron_season1617.groupby('得分')['球员'].count(),color='r')Kawhi_season1617.groupby('得分')['球员'].count().plot(figsize=(12,6),color='b',marker='*')Lebron_season1617.groupby('得分')['球员'].count().plot(figsize=(12,6),color = 'r', marker='o')
横轴:分数,纵轴:发生次数
用柱状图进行对比分析
詹姆斯果然是老司机,稳!其高命中率的场次远高于伦纳德。
角度4:基于抢断和盖帽的分析
steal = data_statistics(Kawhi_season1617, Lebron_season1617, '抢断')stealsteal['K_次数'] = steal['K_次数'] * -1plt.figure(figsize=[16,6])sns.barplot(x = '抢断', y = 'L_次数', data = steal, color='red')sns.barplot(x = '抢断',y = 'K_次数', data = steal, color ='blue')
红色是詹姆斯,蓝色表示伦纳德
横轴表示抢断,纵轴表示发生次数
block = data_statistics(Kawhi_season1617, Lebron_season1617, '盖帽')blockblock['K_次数'] = block['K_次数'] * -1plt.figure(figsize=[16,6])sns.barplot(x = '盖帽', y = 'L_次数', data = block, color='red')sns.barplot(x = '盖帽',y = 'K_次数', data = block, color ='blue')
红色是詹姆斯,蓝色表示伦纳德.
横轴表示盖帽次数,纵轴表示发生次数
可以得到:
伦纳德几乎完爆了詹姆斯。
盖帽上,两人在常规赛平方秋色。
角度5:基于失误次数的分析
fault_num = data_statistics(Kawhi_season1617, Lebron_season1617, '失误')fault_numfault_num['K_次数'] = fault_num['K_次数'] * -1plt.figure(figsize=[16,6])sns.barplot(x = '失误', y = 'L_次数', data = fault_num, color='red')sns.barplot(x = '失误',y = 'K_次数', data = fault_num, color ='blue')
红色是詹姆斯,蓝色表示伦纳德。
横轴表示失误次数,纵轴表示发生次数。
詹姆斯的失误偏高,这也不难理解,伦纳德在波波老爷子手下,失误两个就被换下,詹姆斯没有波波这种教练的限制,另外詹姆斯常常打控卫角色,所以从这一角度来看的话,詹姆斯失误率高也可以理解,不过仅从数据角度来看,不管是自己还是教练的帮忙,伦纳德胜出.
3)最终结论
詹姆斯赢伦纳德:突破能力、组织能力、功能性的差距、稳定性的差距。
詹姆斯输伦纳德:远投能力的差距。小编还是要推荐自己建立的裙Python学习:五七七九零一二九四 这里有推荐的学习路,我们再来分享一下,python2与python3之间的主要区别:
py2:print语句,语句就意味着可以直接跟要打印的东西,如果后面接的是一个元组对象,直接打印
py3:print函数,函数就以为这必须要加上括号才能调用,如果接元组对象,可以接收多个位置参数,并可以打印
如果希望在 Python2 中 把 print 当函数使用,那么可以导入 future 模块 中的 print_function
py2:input_raw()
py3:input()
在使用super()的不同
py2:必须显示的在参数中写上基类
py:直接无参数调用即可
1/2的结果
py2:返回0
py3:返回0.5,没有了int和long的区别
编码
py2:默认编码ascii
py3:默认编码utf-8
而且为了在py2中使用中文,在头部引入coding声明,不推荐使用
迭代器
py2:当中许多返回列表的方法,如range,字典对象的 dict.keys()、dict.values() 方法, map、filter、zip;并且迭代器必须实现next方法
py3:将返回列表的方法改为了返回迭代器对象,内置了__next__,不用特意去实现next
nonlocal
py2:没有办法在嵌套函数中将变量声明为一个非局部变量,只能在函数中声明全局变量
True和False
py2:True 和 False 在 Python2 中是两个全局变量,可以为其赋值或者进行别的操作,初始数值分别为1和0,虽然修改是违背了python设计的原则,但是确实可以更改
py3:修正了这个变量,让True或False不可变
领取专属 10元无门槛券
私享最新 技术干货