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

Python | 英雄联盟游戏数据分析,第1张

Python | 英雄联盟游戏数据分析 一、项目背景

EDG夺得2021英雄联盟全球总决赛冠军,这场比赛让所有观赛者热血沸腾,也唤起了我这个沉睡多年老玩家对MOBA游戏的兴趣,兴冲冲地下载了英雄联盟,却发现这并不是一个可以轻松上手的游戏。
对于时下最流行的MOBA类游戏——英雄联盟,作为一个新手可以从哪些方面切入,通过数据分析了解游戏机制并快速上手,降低新人过渡期的难度,是该项目的中心主题。

二、数据预处理 1.数据来源

数据源:League of Legends Ranked Matches

2.理解数据

数据集包含英雄联盟的18万场对局数据,数据表包括:
champs.csv :包含英雄名称和英雄id
matches.csv : 包含比赛信息
participants : 每场比赛的玩家信息
stats1.csv & stats2.csv : 对战数据
teambans : 队伍ban选数据
teamstats : 队伍总数据

3.数据清洗

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')


可以看到,推塔数和推水晶数是制胜关键因素,毕竟这款游戏是以摧毁对方水晶枢纽为目标的推塔游戏;助攻数和击杀数也极大关系着对局的输赢。

四、分析总结

未完待续……

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5521324.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-13
下一篇 2022-12-13

发表评论

登录后才能评论

评论列表(0条)

保存