写在前面的话
大部分的英雄联盟玩家应该都知道英雄联盟全球总决赛的重要性,这是由Riot Games组织的世界范围内的英雄联盟俱乐部之间的比赛。该项赛事自2011年创办第一届后每年都会在十月为全球的英雄联盟玩家带来世界最强的俱乐部之间的对抗。自该项赛事创办以来,公认实力最强的也是讨论热度最高的两个赛区分别是:韩国赛区以及中国大陆赛区。在已举办的九届全球总决赛中,韩国赛区拿到过5次总冠军,其中SKT的中单选手Faker更是成为每年关注的焦点。但是2018年S8世界赛上中国大陆赛区IG队伍成功登顶不仅圆了众多国内英雄联盟玩家的梦,也让中国大陆赛区重新回归最强赛区之列,而2019年的S9世界赛中国大陆赛区的FPX队伍再一次拿到世界总冠军才正式让韩国赛区退下神坛。经过一代又一代英雄联盟职业选手的努力终于让中国大陆赛区得到了世界范围的认可,也得以让英雄联盟这款游戏在PUBG的冲击下在中国市场能继续维持生命力。
背景介绍
该数据集包含了2019年英雄联盟全球总决赛自入围赛开始所有队伍的数据,包括ban/pick,kda,游戏时长等总共91个字段。这91项游戏数据足以从整体和细节上完整的描述一场游戏,我们会利用这些数据分析各队伍的特点。因为战队之间的比赛和平时游戏里的排位比赛有很大不同,所以红蓝方,ban/pick,各分路经济情况也成为了需要进行分析的点。
下面是该数据集中包含的字段以及对各字段的解释:
date:比赛进行的日期
side:红方或蓝方
position:选手的位置(Top,Middle,Jungle,ADC,Support)
player:选手的ID
team:队伍名称
champion:选手选择的英雄
ban1,ban2,ban3,ban4,ban5:从第一到第五次禁选的英雄
gamelength:游戏时长
result:游戏结果
k,d,a:击杀,死亡,助攻
teamkills,teamdeaths:队伍总击杀,队伍总死亡
doubles,triples,quadras,pentas:双杀,三杀,四杀,五杀
.......(中间包含的众多游戏元素信息因篇幅过长在这里不做解释,分析用到时会另做解释)
数据预处理
首先照例进行数据预处理。
#导入需要用到的包
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
#导入数据
wc_data=pd.read_csv('wc_players.csv')
#看看数据的总量
wc_data.shape
该数据集有1190条数据,91个字段。
接下来看看数据类型以及有没有缺失数据。
#先来看一下数据类型
wc_data.dtypes.value_counts()
#看一下有没有缺失数据
wc_data.isnull().sum().value_counts()
结果显示有两个字段有40个缺失值,一个字段有1190个缺失值,一个字段有5个缺失值。在确定缺失值的处理方式之前要先看看这些值都是什么类型,有什么含义。
#分别找出有缺失值的字段
null_40=wc_data.columns[wc_data.isnull().sum()==40]
null_1190=wc_data.columns[wc_data.isnull().sum()==1190]
null_5=wc_data.columns[wc_data.isnull().sum()==5]
print('Columns with 40 null values:',null_40)
print('Columns with 1190 null values:',null_1190)
print('Columns with 5 null values:',null_5)
得到了有缺值的字段的信息,我们就可以逐一分析如何对缺失值进行处理。对于有40个缺失值的'fbaron' 和 'fbarontime',这两个字段分别表示队伍是否击杀第一条男爵以及击杀第一条男爵的时间,对于这两列缺失值我们直接用'0'填充(注意这里要使用字符串,因为这两列的类型为’object'。再来看有1190条缺失值的字段,'heraldtime' 表示击杀峡谷先锋的时间,因为该列的缺失值过多且无法使用平均数,众数等填充所以直接把这一列删除。最后对于有5个缺失值的'ban5'字段,我们可以选择用第五次禁选最多的英雄填充缺失值。
#为40个缺失值的字段填充0
wc_data['fbaron'].fillna('0',inplace=True)
wc_data['fbarontime'].fillna('0',inplace=True)
#直接删除1190个缺失值的字段
wc_data.drop(columns=['heraldtime'],inplace=True)
#为5个缺失值的字段填充该字段下出现次数最多的英雄
wc_data['ban5'].fillna(wc_data['ban5'].value_counts().index[0],inplace=True)
#检查数据集中现在是否还有缺失值
wc_data.isnull().sum().value_counts()
结果显示我们的缺失处理过程已经完成。
2019全球总决赛包含了两部分:入围赛和正赛,而这两部分无论是队伍实力还是对抗激烈程度都有很大区别,所以我们要把这两部分分开分析。
#把数据分成入围赛部分和正赛部分
#取出入围赛结束日期最后一场比赛最后一个选手对应的index
index=wc_data[wc_data['date']=='2019/10/8'].index[-1]
#分割出入围赛部分
wc_pis=wc_data.iloc[:index+1,:]
#分割出正赛部分
wc_mg=wc_data.iloc[index+1:,:]
到这一步为止,我们的数据预处理就完成了。
探索性数据分析和可视化
我们先对入围赛进行分析。
#先看看入围赛有多少队伍参加
wc_pis['team'].unique()
再来看看入围赛中各位置出场次数最多的英雄。
#入围赛中各位置使用最多的三个英雄及出场次数
wc_pis_top=wc_pis[wc_pis['position']=='Top']['champion'].value_counts()[:3]
wc_pis_jungle=wc_pis[wc_pis['position']=='Jungle']['champion'].value_counts()[:3]
wc_pis_middle=wc_pis[wc_pis['position']=='Middle']['champion'].value_counts()[:3]
wc_pis_adc=wc_pis[wc_pis['position']=='ADC']['champion'].value_counts()[:3]
wc_pis_support=wc_pis[wc_pis['position']=='Support']['champion'].value_counts()[:3]
#可视化
plt.figure(figsize=(20,5))
axe1=plt.subplot(1,5,1)
axe1.bar(np.arange(3),height=wc_pis_top,tick_label=wc_pis_top.index)
axe1.set_title('Top')
axe2=plt.subplot(1,5,2)
axe2.bar(np.arange(3),height=wc_pis_jungle,tick_label=wc_pis_jungle.index)
axe2.set_title('Jungle')
axe3=plt.subplot(1,5,3)
axe3.bar(np.arange(3),height=wc_pis_middle,tick_la