解决方案

Python - 英雄联盟游戏数据分析

seo靠我 2023-09-25 12:55:14

一、项目背景

EDG夺得2021英雄联盟全球总决赛冠军,这场比赛让所有观赛者热血沸腾,也唤起了我这个沉睡多年老玩家对MOBA游戏的兴趣,兴冲冲地下载了英雄联盟,却发现这并不是一个可以轻松上手的游戏。

对于SEO靠我时下最流行的MOBA类游戏——英雄联盟,作为一个新手可以从哪些方面切入,通过数据分析了解游戏机制并快速上手,降低新人过渡期的难度,是该项目的中心主题。

二、数据预处理

1.数据来源

数据源:League oSEO靠我f Legends Ranked Matches

2.理解数据

数据集包含英雄联盟的18万场对局数据,数据表包括:

champs.csv :包含英雄名称和英雄id

matches.csv : 包含比赛信息

paSEO靠我rticipants : 每场比赛的玩家信息

stats1.csv & stats2.csv : 对战数据

teambans : 队伍ban选数据

teamstats : 队伍总数据

3.数据清洗

1.导入数据SEO靠我

导入所有数据表import pandas as pd import numpy as np import matplotlib.pyplot as plt SEO靠我 import seaborn as snschamps=pd.read_csv("champs.csv") matches=pd.read_csv("matches.csv") SEO靠我 participants=pd.read_csv("participants.csv") stats1=pd.read_csv("stats1.csv") SEO靠我 stats2=pd.read_csv("stats2.csv") teambans=pd.read_csv("teambans.csv") teamstats=pd.SEO靠我read_csv("teamstats.csv")

展示champs表:

champs.head()

展示matches表:

matches.head()

展示participants表:

participantSEO靠我s.head()

展示stats1& stats2表,由于列数过多,仅能展示部分:

stats1_shape = stats1.shape print(stats1_shape) SEO靠我 #(999999, 56)

展示teambans表:

teambans.head()

展示teamstats表:

teamstats.head()

2.查找缺失值

计算各表缺失值总和,若缺失值过多再逐列处SEO靠我理 champs_null = sum(champs.isnull().sum()) print(champs_null) #0

各表缺失值均为0,说明数据集完整

3.合并数SEO靠我据表

stats = stats1.append(stats2) df = pd.merge(participants, stats, how= left, on= [id]) SEO靠我 df = pd.merge(df, champs, how= left, left_on= championid, right_on= id) df = pd.merge(dfSEO靠我, matches, how= left, left_on= matchid, right_on= id) df.columns #Index([id_x, matchSEO靠我id, player, championid, ss1, ss2, role, # position, win, item1, item2, item3, item4, item5, SEO靠我item6, # trinket, kills, deaths, assists, largestkillingspree, # largestmultikill, kSEO靠我illingsprees, longesttimespentliving, # doublekills, triplekills, quadrakills, pentakills, SEO靠我 # legendarykills, totdmgdealt, magicdmgdealt, physicaldmgdealt, # truedmgdealt, largeSEO靠我stcrit, totdmgtochamp, magicdmgtochamp, # physdmgtochamp, truedmgtochamp, totheal, totunitshSEO靠我ealed, # dmgselfmit, dmgtoobj, dmgtoturrets, visionscore, timecc, # totdmgtaken, magSEO靠我icdmgtaken, physdmgtaken, truedmgtaken, # goldearned, goldspent, turretkills, inhibkills, SEO靠我 # totminionskilled, neutralminionskilled, ownjunglekills, # enemyjunglekills, totcctimSEO靠我edealt, champlvl, pinksbought, # wardsbought, wardsplaced, wardskilled, firstblood, name, SEO靠我 # id_y, id, gameid, platformid, queueid, seasonid, duration, # creation, version], SEO靠我 # dtype=object)

4.添加必要字段

df[teamid]= df[player].apply(lambda x: 1 if x<5 else 2)#设置团队编号def final_SEO靠我position(row):if row[role] in (DUO_SUPPORT,DUO_CARRY):return row[role]else:return row[position] SEO靠我 df[adjposition]= df.apply(final_position, axis= 1)#整理得到玩家位置信息,包括TOP(上单)、MID(中单)、JUNGLE(打野)、DUO_SSEO靠我UPPORT(辅助)、DUO_CARRY(C位)df[team_role]= df[teamid]+ -+ df[adjposition]#设置玩家角色

三、探索性分析

1.英雄获胜率、KDA

英雄联盟中的SEO靠我英雄众多,新手往往会不知道该怎么选择英雄练手,因此分析哪些英雄更容易取胜,能得到更高得KDA((K击杀数+A助攻数)/ D死亡数),为新手选择英雄提供参考。champs_stats= df.groupSEO靠我by(name).agg({win:sum, name:count, kills:mean, deaths:mean, assists:mean})#分组计算各英雄获胜次数、比赛次数、平均击杀数、平均SEO靠我死亡数、平均助攻数 champs_stats.columns= [win, total matches, K, D, A]#重命名表头 champs_stats[winSEO靠我 rate(%)]= champs_stats[win] / champs_stats[total matches] * 100 #计算获胜率 champs_stats[win ratSEO靠我e-50%]= champs_stats[win rate(%)] - 50 #以50%为基准的胜率 champs_stats[KDA]= (champs_stats[K] + chaSEO靠我mps_stats[A]) / champs_stats[D] #计算KDA champs_stats[KDA-mean]= champs_stats[KDA] - champs_stSEO靠我ats.KDA.mean() #以平均KDA为基准 champs_stats= champs_stats.round(2) #保留两位小数 champs_stats.rSEO靠我eset_index(inplace=True) champs_stats= champs_stats.sort_values(win rate(%),ascending= FalseSEO靠我) #按获胜率降序排列champs_stats.head(10).style.set_precision(2) #获胜率前10的英雄

获胜率排名前10的英雄:

获胜率倒数的10名英雄:

最高获胜率为55.8SEO靠我7%,最低获胜率为39.65%,差值并不算大,为了突出英雄之间获胜率的差异,以50%为基准值,观察所有英雄的获胜率情况:f,ax= plt.subplots(figsize=(10,25)) SEO靠我 sns.barplot(x=win rate-50%,y=name,data= champs_stats.sort_values(by=win rate(%),ascending=False)SEO靠我) plt.title(Win Rate Based on 50%) plt.show()

以KDA平均值为基准值,观察所有英雄的KDA情况:

f,ax= plt.subpSEO靠我lots(figsize=(10,25)) sns.barplot(x=KDA-mean,y=name,data= champs_stats.sort_values(by=KDA,asSEO靠我cending=False)) plt.title(KDA Based on mean) plt.show()

可以看到获胜率在50%以上和50%以下的英雄数量分布相对平SEO靠我衡。获胜率排名前10的英雄里超过一半是法师角色。

KDA最高值是3.81,最低值1.68。KDA排名前10的英雄里以战士/坦克、法师为主,而法师排在头部,考虑到法师在队伍中通常担任辅助角色,能拿到更多助SEO靠我攻;战士/坦克的生存能力、输出能力一般情况下都更强,击杀或助攻数值会比较高。

翠神这个英雄的获胜率和KDA都是所有英雄里最高的,该英雄的官方定位是打野、辅助。

2.英雄出场率

英雄的获胜率高并不代表这个英雄SEO靠我是对新手友好的,这类英雄可能对玩家的游戏技巧和熟练度有很高的要求,因此转向英雄出场率的分析,看看在对局中玩家最常使用的是哪些英雄。f,ax= plt.subplots(figsize=(18,11))SEO靠我 pick_rate= df[name].value_counts().sort_values(ascending= False) #出场次数倒序 ax= pd.conSEO靠我cat((pick_rate.head(10),pick_rate.tail(10))).plot(kind= bar) #取头尾10个做条形图 total_records= len(SEO靠我matches) for x in ax.patches:height= x.get_height()ax.text(x.get_x() + x.get_width()/2.,heigSEO靠我ht,{:.2f}%.format(height/total_records*100),#计算出场率ha= center) #设置数字标签,标注百分比plt.xticks(rotation= 45) SEO靠我#x轴标签旋转 plt.yticks([1500,5000,10000,20000,30000,40000,50000,60000]) #y轴标签 plt.title(SEO靠我Top 10 and Last 10 Pick Rate) plt.show()

可以看到最热门的英雄分别是盲僧、皮城女警、圣枪游侠、魂锁典狱长、九尾妖狐、暗夜猎手、疾风剑豪、发条魔灵、SEO靠我逆羽、探险家,其中只有九尾妖狐在获胜率TOP10里。

出场率最低的10名英雄中,水晶先锋斯卡纳位列获胜率TOP10,可以看出斯卡纳不是绝大多数玩家的选择,但如果能驾驭好这个英雄,可以给团队带来巨大优势。SEO靠我

3.英雄出场次数与获胜率

基于英雄的出场次数和获胜率制作散点图。def lable_point(x, y, val, ax):a= pd.concat({x:x, y:y, val:val}, axisSEO靠我= 1)for i, point in a.iterrows():ax.text(point[x],point[y],str(point[val]))champs_stats[color]= chamSEO靠我ps_stats[win rate(%)].apply(lambda x: red if x>50 else green)ax= champs_stats.plot(kind= scatter, x=SEO靠我 total matches, y= win rate(%),color= champs_stats[color].tolist(),figsize= (18,11),title=Win Rate vSEO靠我s Pick)lable_point(champs_stats[total matches], champs_stats[win rate(%)], champs_stats[name], ax)

可以SEO靠我很明显地看出盲僧的虽然非常热门但是获胜率并不高,翠神则相反地获胜率最高但并不是热门英雄。

新手玩家可以选择获胜率优秀的热门英雄进行练手,比如阿狸、迦娜、亚索等,这类英雄比较好上手,能够提升新手玩家的体验SEO靠我感。

4.取胜相关因素分析

分析获胜与击杀数(kills)、死亡数(deaths)、助攻数(assists)、推塔数(turretkills)、总治疗数(totheal)、补刀数(totminionskiSEO靠我lled)、花费金币总数(goldspent)、总承伤(totdmgtaken)、推水晶数(inhibkills)、插眼数(wardsplaced)、游戏时长(duration)等因素间存在怎样的相关SEO靠我性。df= df[[id, matchid, player, name, adjposition, team_role,win, kills, deaths, assists, turretkillsSEO靠我,totdmgtochamp,totheal, totminionskilled, goldspent, totdmgtaken, inhibkills,pinksbought, wardsplaceSEO靠我d, duration, platformid,seasonid]] #选取需要用的字段df_fac= df._get_numeric_data() df_fac= df_fac.drSEO靠我op([id,matchid,player,seasonid],axis= 1) #去掉不需要分析的字段mask= np.zeros_like(df_fac.corr(), dtype= np.booSEO靠我l) mask[np.triu_indices_from(mask)]= Trueplt.figure(figsize=(18,11)) sns.heatmap(df_SEO靠我fac.corr(), cmap= coolwarm, annot= True, fmt= .2f, linewidths= .5, mask= mask)plt.title(Win Factors)SEO靠我

可以看到,推塔数和推水晶数是制胜关键因素,毕竟这款游戏是以摧毁对方水晶枢纽为目标的推塔游戏;助攻数和击杀数也极大关系着对局的输赢;另外花费金币总数也是重要指标,经济越好,团队的战斗力就会更高,在对剧中SEO靠我更具优势。

四、分析总结

未完待续……

“SEO靠我”的新闻页面文章、图片、音频、视频等稿件均为自媒体人、第三方机构发布或转载。如稿件涉及版权等问题,请与 我们联系删除或处理,客服邮箱:html5sh@163.com,稿件内容仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同 其观点或证实其内容的真实性。

网站备案号:浙ICP备17034767号-2