EDG夺得2021英雄联盟全球总决赛冠军,这场比赛让所有观赛者热血沸腾,也唤起了我这个沉睡多年老玩家对MOBA游戏的兴趣,兴冲冲地下载了英雄联盟,却发现这并不是一个可以轻松上手的游戏。
对于时下最流行的MOBA类游戏——英雄联盟,作为一个新手可以从哪些方面切入,通过数据分析了解游戏机制并快速上手,降低新人过渡期的难度,是该项目的中心主题。
数据源:League of Legends Ranked Matches
2.理解数据数据集包含英雄联盟的18万场对局数据,数据表包括:
champs.csv :包含英雄名称和英雄id
matches.csv : 包含比赛信息
participants : 每场比赛的玩家信息
stats1.csv & stats2.csv : 对战数据
teambans : 队伍ban选数据
teamstats : 队伍总数据
1.导入数据
导入所有数据表
import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns champs=pd.read_csv("champs.csv") matches=pd.read_csv("matches.csv") participants=pd.read_csv("participants.csv") stats1=pd.read_csv("stats1.csv") stats2=pd.read_csv("stats2.csv") teambans=pd.read_csv("teambans.csv") teamstats=pd.read_csv("teamstats.csv")
展示champs表:
champs.head()
展示matches表:
matches.head()
展示participants表:
participants.head()
展示stats1& stats2表,由于列数过多,仅能展示部分:
stats1_shape = stats1.shape print(stats1_shape) #(999999, 56)
展示teambans表:
teambans.head()
展示teamstats表:
teamstats.head()
2.查找缺失值
计算各表缺失值总和,若缺失值过多再逐列处理
champs_null = sum(champs.isnull().sum()) print(champs_null) #0
各表缺失值均为0,说明数据集完整
3.合并数据表
stats = stats1.append(stats2) df = pd.merge(participants, stats, how= 'left', on= ['id']) df = pd.merge(df, champs, how= 'left', left_on= 'championid', right_on= 'id') df = pd.merge(df, matches, how= 'left', left_on= 'matchid', right_on= 'id') df.columns #Index(['id_x', 'matchid', 'player', 'championid', 'ss1', 'ss2', 'role', # 'position', 'win', 'item1', 'item2', 'item3', 'item4', 'item5', 'item6', # 'trinket', 'kills', 'deaths', 'assists', 'largestkillingspree', # 'largestmultikill', 'killingsprees', 'longesttimespentliving', # 'doublekills', 'triplekills', 'quadrakills', 'pentakills', # 'legendarykills', 'totdmgdealt', 'magicdmgdealt', 'physicaldmgdealt', # 'truedmgdealt', 'largestcrit', 'totdmgtochamp', 'magicdmgtochamp', # 'physdmgtochamp', 'truedmgtochamp', 'totheal', 'totunitshealed', # 'dmgselfmit', 'dmgtoobj', 'dmgtoturrets', 'visionscore', 'timecc', # 'totdmgtaken', 'magicdmgtaken', 'physdmgtaken', 'truedmgtaken', # 'goldearned', 'goldspent', 'turretkills', 'inhibkills', # 'totminionskilled', 'neutralminionskilled', 'ownjunglekills', # 'enemyjunglekills', 'totcctimedealt', 'champlvl', 'pinksbought', # 'wardsbought', 'wardsplaced', 'wardskilled', 'firstblood', 'name', # 'id_y', 'id', 'gameid', 'platformid', 'queueid', 'seasonid', 'duration', # 'creation', 'version'], # dtype='object')
4.添加必要字段
df['teamid']= df['player'].apply(lambda x: '1' if x<5 else '2')#设置团队编号 def final_position(row): if row['role'] in ('DUO_SUPPORT','DUO_CARRY'): return row['role'] else: return row['position'] df['adjposition']= df.apply(final_position, axis= 1)#整理得到玩家位置信息,包括TOP(上单)、MID(中单)、JUNGLE(打野)、DUO_SUPPORT(辅助)、DUO_CARRY(C位) df['team_role']= df['teamid']+ '-'+ df['adjposition']#设置玩家角色三、探索性分析
1.英雄获胜率、KDA
英雄联盟中的英雄众多,新手往往会不知道该怎么选择英雄练手,因此分析哪些英雄更容易取胜,能得到更高得KDA((K击杀数+A助攻数)/ D死亡数),为新手选择英雄提供参考。
champs_stats= df.groupby('name').agg({'win':'sum', 'name':'count', 'kills':'mean', 'deaths':'mean', 'assists':'mean'})#分组计算各英雄获胜次数、比赛次数、平均击杀数、平均死亡数、平均助攻数 champs_stats.columns= ['win', 'total matches', 'K', 'D', 'A']#重命名表头 champs_stats['win rate(%)']= champs_stats['win'] / champs_stats['total matches'] * 100 #计算获胜率 champs_stats['win rate-50%']= champs_stats['win rate(%)'] - 50 #以50%为基准的胜率 champs_stats['KDA']= (champs_stats['K'] + champs_stats['A']) / champs_stats['D'] #计算KDA champs_stats['KDA-mean']= champs_stats['KDA'] - champs_stats.KDA.mean() #以平均KDA为基准 champs_stats= champs_stats.round(2) #保留两位小数 champs_stats.reset_index(inplace=True) champs_stats= champs_stats.sort_values('win rate(%)',ascending= False) #按获胜率降序排列 champs_stats.head(10).style.set_precision(2) #获胜率前10的英雄
获胜率排名前10的英雄:
获胜率倒数的10名英雄:
最高获胜率为55.87%,最低获胜率为39.65%,差值并不算大,为了突出英雄之间获胜率的差异,以50%为基准值,观察所有英雄的获胜率情况:
f,ax= plt.subplots(figsize=(10,25)) sns.barplot(x='win rate-50%',y='name',data= champs_stats.sort_values(by='win rate(%)',ascending=False)) plt.title('Win Rate based on 50%') plt.show()
以KDA平均值为基准值,观察所有英雄的KDA情况:
f,ax= plt.subplots(figsize=(10,25)) sns.barplot(x='KDA-mean',y='name',data= champs_stats.sort_values(by='KDA',ascending=False)) plt.title('KDA based on mean') plt.show()
可以看到获胜率在50%以上和50%以下的英雄数量分布相对平衡。获胜率排名前10的英雄里超过一半是法师角色。
KDA最高值是3.81,最低值1.68。KDA排名前10的英雄里以战士/坦克、法师为主,而法师排在头部,考虑到法师在队伍中通常担任辅助角色,能拿到更多助攻;战士/坦克的生存能力、输出能力一般情况下都更强,击杀或助攻数值会比较高。
翠神这个英雄的获胜率和KDA都是所有英雄里最高的,该英雄的官方定位是打野、辅助。
2.英雄出场率
3.英雄出场率与获胜率
4.取胜相关因素分析
分析获胜与击杀数(kills)、死亡数(deaths)、助攻数(assists)、推塔数(turretkills)、总治疗数(totheal)、补刀数(totminionskilled)、花费金币总数(goldspent)、总承伤(totdmgtaken)、推水晶数(inhibkills)、插眼数(wardsplaced)、游戏时长(duration)等因素间存在怎样的相关性。
df= df[['id', 'matchid', 'player', 'name', 'adjposition', 'team_role', 'win', 'kills', 'deaths', 'assists', 'turretkills','totdmgtochamp', 'totheal', 'totminionskilled', 'goldspent', 'totdmgtaken', 'inhibkills', 'pinksbought', 'wardsplaced', 'duration', 'platformid', 'seasonid']] #选取需要用的字段 df_fac= df._get_numeric_data() df_fac= df_fac.drop(['id','matchid','player','seasonid'],axis= 1) #去掉不需要分析的字段 mask= np.zeros_like(df_fac.corr(), dtype= np.bool) mask[np.triu_indices_from(mask)]= True plt.figure(figsize=(18,11)) sns.heatmap(df_fac.corr(), cmap= 'coolwarm', annot= True, fmt= '.2f', linewidths= .5, mask= mask) plt.title('Win Factors')
可以看到,推塔数和推水晶数是制胜关键因素,毕竟这款游戏是以摧毁对方水晶枢纽为目标的推塔游戏;助攻数和击杀数也极大关系着对局的输赢。
未完待续……
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)