共计 2885 个字符,预计需要花费 8 分钟才能阅读完成。
前言
1. 这篇数据分析案例,我做了个 视频版本,对代码做了解读,讲了运行的注意事项和一些有的没的,供需。对于视频制作还不是很有教训,多包涵。(视频里有彩蛋)
NBA 球星出手点散布 https://www.zhihu.com/video/1129401682580348928
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/nba_py/
通过以下接口,咱们能够获取某个球员在指定赛季的投篮具体数据:
https://stats.nba.com/stats/shotchartdetail?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/202391/
链接中的两处 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)
咱们关怀的数据就是 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)
咱们通过参数设定点的大小和透明度,让显示更分明。
4. 绘制球场
投篮点画进去了,不过只是这样不够直观。咱们再来加个球场的图。
这个是通过 matplotlib 里的 Circle、Rectangle、Arc 等办法拼出来的,没啥特地的技术,但代码比拟繁琐,这边就不贴了。(只有你违心,甚至能够用它画出小猪佩奇)
5. 增加头像
最初,再给数据图加上一个头像,让它看起来更残缺。头像地址:
https://stats.nba.com/media/players/230×185/202391.png
或者
https://ak-static.cms.nba.com/wp-content/uploads/headshots/nba/latest/260×190/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 的值(不同零碎,甚至不同编译器都可能存在差别)。
最终成果:
获取原图、更多球员生成的后果及残缺代码,请在公众号“Crossin 的编程教室”内回复关键字:nba