绝地求生游戏数据分析-愉快吃鸡

image.png

学习数据分析,熟悉pandas, numpy这两个数据分析必备武器,再利用seaborn画图,这个比matplpotlib更容易使用.

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns 
import warnings
warnings.filterwarnings("ignore")

train = pd.read_csv('../input/train.csv')

train.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 4357336 entries, 0 to 4357335
Data columns (total 26 columns):
Id                 int64
groupId            int64
matchId            int64
assists            int64
boosts             int64
damageDealt        float64
DBNOs              int64
headshotKills      int64
heals              int64
killPlace          int64
killPoints         int64
kills              int64
killStreaks        int64
longestKill        float64
maxPlace           int64
numGroups          int64
revives            int64
rideDistance       float64
roadKills          int64
swimDistance       float64
teamKills          int64
vehicleDestroys    int64
walkDistance       float64
weaponsAcquired    int64
winPoints          int64
winPlacePerc       float64
dtypes: float64(6), int64(20)
memory usage: 864.3 MB
  • groupId -用于标识匹配中的组的整数ID。 如果同一组玩家在不同的比赛中比赛,他们每次都会有不同的groupId
  • matchId - 用于标识匹配的整数ID。 训练和测试集中都没有匹配项。
  • assists - 伤害敌方数量,最后敌方被队友杀掉
  • boosts - 使用的增强项数。
  • damageDealt - 造成的总伤害。 注意:减去自己造成的伤害
  • DBNOs - 击倒的敌人数量
  • headshotKills - 爆头击毙的敌方玩家数量
  • heals - 使用的治疗项目数
  • killPlace - 在杀死的敌方玩家数量的比赛排名。
  • killPoints - 基于杀戮的玩家外部排名. (把它想象成一个Elo排名只会杀死很重要)
  • kills - 杀死的敌方玩家数量。
  • killStreaks - 在很短的时间内杀死敌方玩家的最大数量
  • longestKill - 玩家和玩家在死亡时被杀的最长距离. 这可能会产生误导,因为击倒一个玩家并且开走可能会导致最长的杀戮统计数据。
  • maxPlace - 我们在比赛中的位置。 这可能与numGroups不匹配,因为有时数据会跳过展示位置.
  • numGroups - 我们在比赛中有数据的组.
  • revives -这名队员复活队友的次数.
  • rideDistance - 以米为单位测量车辆总行驶距离
  • roadKills -在车辆中的杀人次数
  • swimDistance - 游泳的总距离以米为单位
  • teamKills - 该玩家杀死队友的次数
  • vehicleDestroys - 被摧毁的车辆数量
  • walkDistance - 徒步旅行的总距离以米为单位
  • weaponsAcquired - 拾取的武器数量
  • winPoints - 基于赢的玩家外部排名。 (将此视为Elo排名,只有获胜才有意义。)
  • winPlacePerc - 预测的目标。 这是一个百分位获胜位置,其中1对应于第一名,0对应于比赛中的最后一名。 它是根据maxPlace计算的,而不是numGroups,因此匹配中可能缺少块
train.head()
image.png

好了,现在我们已经看到了数据,让我们来探索一下。

杀人者

print("平均每一个人杀 {:.4f} 玩家, 一次杀{}个人就打败99% 玩家 , 杀人最多玩家一次杀了{}.".format(train['kills'].mean(),train['kills'].quantile(0.99), train['kills'].max()))
平均每一个人杀0.9345玩家, 一次杀7个人就打败99% 玩家 , 杀人最多玩家一次杀了60.

让我们描绘一下杀人数。

data = train.copy()
data.loc[data['kills'] > data['kills'].quantile(0.99)] = '8+'
plt.figure(figsize=(15,10))
sns.countplot(data['kills'].astype('str').sort_values())
plt.title("Kill Count",fontsize=15)
plt.show()
image.png

大多数人无法杀死一个人。 那么他们能造成伤害吗?

data = train.copy()
data = data[data['kills']==0]
plt.figure(figsize=(15,10))
plt.title("Damage Dealt by 0 killers",fontsize=15)
sns.distplot(data['damageDealt'])
plt.show()
image.png

好吧,大多数人都没有给别人造成伤害。 我们来研究一下例外情况。

print("{} 玩家 ({:.4f}%) 不用杀一个人就可以赢得比赛".format(len(data[data['winPlacePerc']==1]), 100*len(data[data['winPlacePerc']==1])/len(train)))

data1 = train[train['damageDealt'] == 0].copy()
print("{} 玩家 ({:.4f}%) 不用伤害任何人就可以躺赢比赛".format(len(data1[data1['winPlacePerc']==1]), 100*len(data1[data1['winPlacePerc']==1])/len(train)))
16722 玩家 (0.3838%) 不用杀一个人就可以赢得比赛
4262 玩家 (0.0978%) 不用伤害任何人就可以躺赢比赛

杀人数量和赢率排位关系

sns.jointplot(x="winPlacePerc", y="kills", data=train, height=10, ratio=3, color="r")
plt.show()
image.png

非常明显,杀人与获胜有关。 最后让我们根据杀人数量(0杀,1-2杀,3-5杀,6-10杀和10+杀)组成玩家。

kills = train.copy()

kills['killsCategories'] = pd.cut(kills['kills'], [-1, 0, 2, 5, 10, 60], labels=['0_kills','1-2_kills', '3-5_kills', '6-10_kills', '10+_kills'])

plt.figure(figsize=(15,8))
sns.boxplot(x="killsCategories", y="winPlacePerc", data=kills)
plt.show()
image.png

跑步者

image.png
print("平均每人走{:.1f}m, 走了{}m就可以击败99%的人, 而马拉松冠军走了 {}m.".format(train['walkDistance'].mean(), train['walkDistance'].quantile(0.99), train['walkDistance'].max()))
平均每人走1055.1m,走了4138.0m就可以击败99%的人,而马拉松冠军走了17300.0m。
data = train.copy()
data = data[data['walkDistance'] < train['walkDistance'].quantile(0.99)]
plt.figure(figsize=(15,10))
plt.title("Walking Distance Distribution",fontsize=15)
sns.distplot(data['walkDistance'])
plt.show()
image.png
print("{} 名玩家 ({:.4f}%) 走了0米. 这意味着他们落地成灰了或者他们是断线了(更有可能)".format(len(data[data['walkDistance'] == 0]), 100*len(data1[data1['walkDistance']==0])/len(train)))
94306名玩家(2.0581%)走了0米。 这意味着他们落地成灰了或者他们是断线了(更有可能)。
sns.jointplot(x="winPlacePerc", y="walkDistance",  data=train, height=10, ratio=3, color="lime")
plt.show()
image.png

显然,步行与胜率有很高的相关性。走到最后的人,就是赢家!

治疗师

print("普通人使用 {:.1f} 次治疗项目, 使用{}次就超过99%的人, 而最厉害的救死扶伤者使用{}次.".format(train['heals'].mean(), train['heals'].quantile(0.99), train['heals'].max()))
print("普通人使用 {:.1f} 次增强物品, 使用{}次就超过99% 的人, 而有人最多使用{}次.".format(train['boosts'].mean(), train['boosts'].quantile(0.99), train['boosts'].max()))
普通人使用1.2次治疗项目,使用11.0次就超过99%的人,而最厉害的救死扶伤者使用59次.
普通人使用1.0次增强物品,使用7.0次就超过99%的人,而有人最多使用18次.
data = train.copy()
data = data[data['heals'] < data['heals'].quantile(0.99)]
data = data[data['boosts'] < data['boosts'].quantile(0.99)]

f,ax1 = plt.subplots(figsize =(20,10))
sns.pointplot(x='heals',y='winPlacePerc',data=data,color='lime',alpha=0.8)
sns.pointplot(x='boosts',y='winPlacePerc',data=data,color='blue',alpha=0.8)
plt.text(4,0.6,'Heals',color='lime',fontsize = 17,style = 'italic')
plt.text(4,0.55,'Boosts',color='blue',fontsize = 17,style = 'italic')
plt.xlabel('Number of heal/boost items',fontsize = 15,color='blue')
plt.ylabel('Win Percentage',fontsize = 15,color='blue')
plt.title('Heals vs Boosts',fontsize = 20,color='blue')
plt.grid()
plt.show()
image.png
sns.jointplot(x="winPlacePerc", y="heals", data=train, height=10, ratio=3, color="lime")
plt.show()
image.png
sns.jointplot(x="winPlacePerc", y="boosts", data=train, height=10, ratio=3, color="blue")
plt.show()
image.png

所以补血和增强物品,肯定与胜率相关.

在每个图中,当值为0时,存在异常行为。

单挑, 二人和组队

游戏中有3种游戏模式。 一个人可以单独作战,或与朋友(二人组),或与其他3个朋友(小队)一起玩。 100名玩家加入同一台服务器,因此在二人组的情况下,最大的队伍是50,而在小队的情况下,最大队伍是25。

solos = train[train['numGroups']>50]
duos = train[(train['numGroups']>25) & (train['numGroups']<=50)]
squads = train[train['numGroups']<=25]
print(" 有{} ({:.2f}%) 单人作战, {} 个({:.2f}%) 二人组队和 {} 个({:.2f}%) 三人或以上组队".format(len(solos), 100*len(solos)/len(train), len(duos), 100*len(duos)/len(train), len(squads), 100*len(squads)/len(train),))
有563279个(12.93%)单人作战, 3070150个(70.46%)二人组队和723907个(16.61%)三人或以上组队
f,ax1 = plt.subplots(figsize =(20,10))
sns.pointplot(x='kills',y='winPlacePerc',data=solos,color='black',alpha=0.8)
sns.pointplot(x='kills',y='winPlacePerc',data=duos,color='#CC0000',alpha=0.8)
sns.pointplot(x='kills',y='winPlacePerc',data=squads,color='#3399FF',alpha=0.8)
plt.text(37,0.6,'Solos',color='black',fontsize = 17,style = 'italic')
plt.text(37,0.55,'Duos',color='#CC0000',fontsize = 17,style = 'italic')
plt.text(37,0.5,'Squads',color='#3399FF',fontsize = 17,style = 'italic')
plt.xlabel('Number of kills',fontsize = 15,color='blue')
plt.ylabel('Win Percentage',fontsize = 15,color='blue')
plt.title('Solo vs Duo vs Squad Kills',fontsize = 20,color='blue')
plt.grid()
plt.show()
image.png

嗯,非常有趣. 一个人和二人组的表现相同,但是当打小队时杀人并不重要的参数。

变量之间的相关性

f,ax = plt.subplots(figsize=(15, 15))
sns.heatmap(train.corr(), annot=True, linewidths=.5, fmt= '.1f',ax=ax)
plt.show()
image.png

就目标变量(winPlacePerc)而言,存在一些高中高相关变量。 最高正相关是walkDistance,最高负相关killPlace。

让我们放大到与目标相关的前5个最正相关变量。

k = 5 #number of variables for heatmap
f,ax = plt.subplots(figsize=(11, 11))
cols = train.corr().nlargest(k, 'winPlacePerc')['winPlacePerc'].index
cm = np.corrcoef(train[cols].values.T)
sns.set(font_scale=1.25)
hm = sns.heatmap(cm, cbar=True, annot=True, square=True, fmt='.2f', annot_kws={'size': 10}, yticklabels=cols.values, xticklabels=cols.values)
plt.show()
image.png

游戏最多可以有100名玩家互相争斗。 但大多数时候游戏都不是“满员”。 没有变量可以为我们提供加入的玩家数量。 所以让我们创建一个。

train['playersJoined'] = train.groupby('matchId')['matchId'].transform('count')
data = train.copy()
data = data[data['playersJoined']>49]
plt.figure(figsize=(15,10))
sns.countplot(data['playersJoined'])
plt.title("Players Joined",fontsize=15)
plt.show()
image.png

有兴趣的朋友可以下载数据,自己玩一下

链接: https://pan.baidu.com/s/1wYYq4P67zhY87UiB8H8raA 提取码: mcqj

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,284评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,115评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,614评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,671评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,699评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,562评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,309评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,223评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,668评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,859评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,981评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,705评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,310评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,904评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,023评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,146评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,933评论 2 355

推荐阅读更多精彩内容

  • 还记得小编第一次吃鸡的时候,落地3分钟就被毙、跑不过毒倒在半路上失血致死、站在草丛中被不明方向的子弹狙击而亡、出门...
    哈哈哈_53b3阅读 687评论 0 3
  • 每天微博上都能看到出轨小三渣男的消息,这种微博下面每条评论都很愤怒都很义愤填膺都在表达自己对小三渣男的不齿,但是我...
    艾斯没有利阅读 287评论 0 0
  • 今天下午第二节课上了体育,体育老师让我们排队,过了一会儿体育就让我们开始跑步,我跑的非常快,跑完了老师又让我们自己...
    李嘉宝1阅读 627评论 0 0
  • 今天周末,早上八点多格格才起来,还要赖床,我没让。她自己起来穿好衣服吃完早饭,自己开始写语文课时题,写完不检查给我...
    柳依函妈妈阅读 170评论 0 0
  • 使用spring boot整合flink可以快速的构建起整个应用,将关注点重点放在业务逻辑的实现上。在整合的过程中...
    Java程序员YY阅读 6,682评论 0 8