python爬取电竞《绝地求生》比赛数据集分析

      python爬取电竞《绝地求生》比赛数据集分析

一,选题背景

  电子竞技(Electronic Sports)是电子游戏比赛达到“竞技”层面的体育项目。电子竞技就是利用电子设备作为运动器械进行的、人与人之间的智力和体力结合的比拼。通过电子竞技,可以锻炼和提高参与者的思维能力、反应能力、四肢协调能力和意志力,培养团队精神,并且职业电竞对体力也有较高要求。电子竞技也是一种职业,和棋艺等非电子游戏比赛类似,2003年11月18日,国家体育局正式批准,将电子竞技列为第99个正式体育竞赛项目。2008年,国家体育总局将电子竞技改批为第78号正式体育竞赛项目。2018年雅加达亚运会将电子竞技纳为表演项目。数据来源:20G绝地求生比赛数据集。

 

二,设计方案

1,爬虫名称:python爬取电竞《绝地求生》比赛数据集分析

2,爬虫爬取的内容与数据特征分析

  主要分成两部分,一部分是玩家比赛的统计数据,以agg_match_stats开头,一部分是玩家被击杀的数据,以kill_match_stats开头本次分析选取其中的两个数据集进行分析

3,设计方案:

  1. 飞机嗡嗡地,我到底跳哪里比较安全?

  2. 我是该苟着不动,还是应该出去猛干?

  3. 是该单打独斗还是跟队友一起配合?

  4. 毒来了我跑不过毒怎么办啊?

  5. 什么武器最有用?

  6. 近战适合使用什么武器,狙击适合使用什么武器呢?

  7. 最后的毒圈一般会在哪里呢?

 

三,结果特征分析

1,页面的结构与特征分析

 

 

 

 

 

 四,程序设计

1,# 使用pandas读取数据

 1 import pandas as pd
 2 import numpy as np
 3 import matplotlib.pyplot as plt
 4 import seaborn as sns
 5 %matplotlib inline
 6 plt.rcParams['font.sans-serif'] = ['SimHei'] # 指定默认字体
 7 plt.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题
 8 
 9 # 使用pandas读取数据
10 agg1 = pd.read_csv('/Users/apple/Desktop/pubg/aggregate/agg_match_stats_1.csv')

 

2,# 探索数据结构并数据清洗

1 agg1.head()

 

 

 

 

# 总共有13844275行玩家数据,15列

1 agg1.shape

 

 

1 agg1.columns

 

 

 

 

1  agg1.info()

 

 

 

 3,数据分析与可视化

# 丢弃重复数据

1 agg1.drop_duplicates(inplace=True)
2 
3 agg1.loc[1]

 

 

 

 # 添加是否成功吃鸡列

1 agg1['won'] = agg1['team_placement'] == 1

 

# 添加是否搭乘过车辆列

1 agg1['drove'] = agg1['player_dist_ride'] != 0

 

 

我是该苟着不动,还是应该出去猛干

1 agg1.loc[agg1['player_kills'] < 40, ['player_kills', 'won']].groupby('player_kills').won.mean().plot.bar(figsize=(15,6), rot=0)
2 plt.xlabel('击杀人数', fontsize=14)
3 plt.ylabel("吃鸡概率", fontsize=14)
4 plt.title('击杀人数与吃鸡概率的关系', fontsize=14)

 

 

 

 不同模式下的平均击杀人数:

1 agg1.groupby('party_size').player_kills.mean()

 

 

 

 

 

 

 

1 g = sns.FacetGrid(agg1.loc[agg1['player_kills']<=10, ['party_size', 'player_kills']], row="party_size", size=4, aspect=2)
2 g = g.map(sns.countplot, "player_kills")
3 
4 
5 
6 party_size=1

 

 

 

1  party_size=2

 

 

 

1   party_size=4

 

 

 

 是该单打独斗还是跟队友一起配合?

1 agg1.loc[agg1['party_size']!=1, ['player_assists', 'won']].groupby('player_assists').won.mean().plot.bar(figsize=(15,6), rot=0)
2 plt.xlabel('助攻次数', fontsize=14)
3 plt.ylabel("吃鸡概率", fontsize=14)
4 plt.title('助攻次数与吃鸡概率的关系', fontsize=14)

 

 

 

 “毒来了我跑不过毒怎么办啊”之车辆到底有多重要?

1 agg1.groupby('drove').won.mean().plot.barh(figsize=(6,3))
2 plt.xlabel("吃鸡概率", fontsize=14)
3 plt.ylabel("是否搭乘过车辆", fontsize=14)
4 plt.title('搭乘车辆与吃鸡概率的关系', fontsize=14)
5 plt.yticks([1,0],['',''])

 

 

 

 

 

1 dist_ride = agg1.loc[agg1['player_dist_ride']<12000, ['player_dist_ride', 'won']]
2 
3 labels=["0-1k", "1-2k", "2-3k", "3-4k","4-5k", "5-6k", "6-7k", "7-8k", "8-9k", "9-10k", "10-11k", "11-12k"]
4 dist_ride['drove_cut'] = pd.cut(dist_ride['player_dist_ride'], 12, labels=labels)
5 
6 dist_ride.groupby('drove_cut').won.mean().plot.bar(rot=60, figsize=(8,4))
7 plt.xlabel("搭乘车辆里程", fontsize=14)
8 plt.ylabel("吃鸡概率", fontsize=14)
9 plt.title('搭乘车辆里程与吃鸡概率的关系', fontsize=14)

 

 

 

 

 match_unique = agg1.loc[agg1['party_size'] == 1, 'match_id'].unique()

match_unique = agg1.loc[agg1['party_size'] == 1, 'match_id'].unique()
 

把玩家被击杀的数据导入进来

1 # 先把玩家被击杀的数据导入进来并探索数据
2 death1 = pd.read_csv('/Users/apple/Desktop/pubg/deaths/kill_match_stats_final_1.csv')
3 
4 death1.head()

 

 

 

 

1 death1.info()
2 
3 death1.shape
4 
5 death1_solo = death1[death1['match_id'].isin(match_unique)]
6 
7 death1_solo.info()

 

 

 

 

 

 

 飞机嗡嗡地,我到底跳哪里比较安全

 

1 # 只统计单人模式,筛选存活不超过180秒的玩家数据
2 death_180_seconds_erg = death1_solo.loc[(death1_solo['map'] == 'ERANGEL')&(death1_solo['time'] < 180)&(death1_solo['victim_position_x']>0), :].dropna()
3 death_180_seconds_mrm = death1_solo.loc[(death1_solo['map'] == 'MIRAMAR')&(death1_solo['time'] < 180)&(death1_solo['victim_position_x']>0), :].dropna()
4 
5 death_180_seconds_erg.shape
6 
7 death_180_seconds_mrm.shape

 

 

 

 

 1 # 选择存活不过180秒的玩家死亡位置
 2 data_erg = death_180_seconds_erg[['victim_position_x', 'victim_position_y']].values
 3 data_mrm = death_180_seconds_mrm[['victim_position_x', 'victim_position_y']].values
 4 
 5 # 重新scale玩家位置
 6 data_erg = data_erg*4096/800000
 7 data_mrm = data_mrm*1000/800000
 8 
 9 from scipy.ndimage.filters import gaussian_filter
10 import matplotlib.cm as cm
11 from matplotlib.colors import Normalize
12 from scipy.misc.pilutil import imread
13 
14 from scipy.ndimage.filters import gaussian_filter
15 import matplotlib.cm as cm
16 from matplotlib.colors import Normalize
17 
18 def heatmap(x, y, s, bins=100):
19 heatmap, xedges, yedges = np.histogram2d(x, y, bins=bins)
20 heatmap = gaussian_filter(heatmap, sigma=s)
21 
22 extent = [xedges[0], xedges[-1], yedges[0], yedges[-1]]
23 return heatmap.T, extent
24 
25 bg = imread('/Users/apple/Desktop/pubg/erangel.jpg')
26 hmap, extent = heatmap(data_erg[:,0], data_erg[:,1], 4.5)
27 alphas = np.clip(Normalize(0, hmap.max(), clip=True)(hmap)*4.5, 0.0, 1.)
28 colors = Normalize(0, hmap.max(), clip=True)(hmap)
29 colors = cm.Reds(colors)
30 colors[..., -1] = alphas
31 
32 fig, ax = plt.subplots(figsize=(24,24))
33 ax.set_xlim(0, 4096); ax.set_ylim(0, 4096)
34 ax.imshow(bg)
35 ax.imshow(colors, extent=extent, origin='lower', cmap=cm.Reds, alpha=0.9)
36 plt.gca().invert_yaxis()

 

 

 

 

 1 bg = imread('/Users/apple/Desktop/pubg/miramar.jpg')
 2 hmap, extent = heatmap(data_mrm[:,0], data_mrm[:,1], 4)
 3 alphas = np.clip(Normalize(0, hmap.max(), clip=True)(hmap)*4, 0.0, 1.)
 4 colors = Normalize(0, hmap.max(), clip=True)(hmap)
 5 colors = cm.Reds(colors)
 6 colors[..., -1] = alphas
 7 
 8 fig, ax = plt.subplots(figsize=(24,24))
 9 ax.set_xlim(0, 1000); ax.set_ylim(0, 1000)
10 ax.imshow(bg)
11 ax.imshow(colors, extent=extent, origin='lower', cmap=cm.Reds, alpha=0.9)
12 #plt.scatter(plot_data_mr[:,0], plot_data_mr[:,1])
13 plt.gca().invert_yaxis()

 

 

 

 

 最后的毒圈一般会在哪里呢?

这里选取每场比赛第一名和第二名的位置数据,因为第一名和第二名所在的位置基本上就是最后的毒圈所在的位置

 1 death_final_circle_erg = death1_solo.loc[(death1_solo['map'] == 'ERANGEL')&(death1_solo['victim_placement'] == 2)&(death1_solo['victim_position_x']>0)&(death1_solo['killer_position_x']>0), :].dropna()
 2 death_final_circle_mrm = death1_solo.loc[(death1_solo['map'] == 'MIRAMAR')&(death1_solo['victim_placement'] == 2)&(death1_solo['victim_position_x']>0)&(death1_solo['killer_position_x']>0), :].dropna()
 3 
 4 print(death_final_circle_erg.shape)
 5 print(death_final_circle_mrm.shape)
 6 
 7 final_circle_erg = np.vstack([death_final_circle_erg[['victim_position_x', 'victim_position_y']].values,
 8 death_final_circle_erg[['killer_position_x', 'killer_position_y']].values])*4096/800000
 9 final_circle_mrm = np.vstack([death_final_circle_mrm[['victim_position_x', 'victim_position_y']].values,
10 death_final_circle_mrm[['killer_position_x', 'killer_position_y']].values])*1000/800000

 

 

 

 

 1 bg = imread('/Users/apple/Desktop/pubg/erangel.jpg')
 2 hmap, extent = heatmap(final_circle_erg[:,0], final_circle_erg[:,1], 1.5)
 3 alphas = np.clip(Normalize(0, hmap.max(), clip=True)(hmap)*1.5, 0.0, 1.)
 4 colors = Normalize(0, hmap.max(), clip=True)(hmap)
 5 colors = cm.Reds(colors)
 6 colors[..., -1] = alphas
 7 
 8 fig, ax = plt.subplots(figsize=(24,24))
 9 ax.set_xlim(0, 4096); ax.set_ylim(0, 4096)
10 ax.imshow(bg)
11 ax.imshow(colors, extent=extent, origin='lower', cmap=cm.Reds, alpha=0.9)
12 #plt.scatter(plot_data_er[:,0], plot_data_er[:,1])
13 
14 plt.gca().invert_yaxis()

 

 

 

 

 1 bg = imread('/Users/apple/Desktop/pubg/miramar.jpg')
 2 hmap, extent = heatmap(final_circle_mrm[:,0], final_circle_mrm[:,1], 1.5)
 3 alphas = np.clip(Normalize(0, hmap.max(), clip=True)(hmap)*1.5, 0.0, 1.)
 4 colors = Normalize(0, hmap.max(), clip=True)(hmap)
 5 colors = cm.Reds(colors)
 6 colors[..., -1] = alphas
 7 
 8 fig, ax = plt.subplots(figsize=(24,24))
 9 ax.set_xlim(0, 1000); ax.set_ylim(0, 1000)
10 ax.imshow(bg)
11 ax.imshow(colors, extent=extent, origin='lower', cmap=cm.Reds, alpha=0.9)
12 #plt.scatter(plot_data_mr[:,0], plot_data_mr[:,1])
13 plt.gca().invert_yaxis()

 

 

 

 什么武器最有用?

1 erg_died_of = death1.loc[(death1['map']=='ERANGEL')&(death1['killer_position_x']>0)&(death1['victim_position_x']>0)&(death1['killed_by']!='Down and Out'),:]
2 mrm_died_of = death1.loc[(death1['map']=='MIRAMAR')&(death1['killer_position_x']>0)&(death1['victim_position_x']>0)&(death1['killed_by']!='Down and Out'),:]
3 
4 print(erg_died_of.shape)
5 print(mrm_died_of.shape)

 

 

 

 

1 erg_died_of['killed_by'].value_counts()[:10].plot.barh(figsize=(10,5))
2 plt.xlabel("被击杀人数", fontsize=14)
3 plt.ylabel("击杀的武器", fontsize=14)
4 plt.title('武器跟击杀人数的统计(绝地海岛艾伦格)', fontsize=14)
5 plt.yticks(fontsize=12)

 

 

 

 

狙击适合使用什么武器?

 

 1 # 把位置信息转换成距离,以“米”为单位
 2 erg_distance = np.sqrt(((erg_died_of['killer_position_x']-erg_died_of['victim_position_x'])/100)**2 + ((erg_died_of['killer_position_y']-erg_died_of['victim_position_y'])/100)**2)
 3 
 4 
 5 
 6 mrm_distance = np.sqrt(((mrm_died_of['killer_position_x']-mrm_died_of['victim_position_x'])/100)**2 + ((mrm_died_of['killer_position_y']-mrm_died_of['victim_position_y'])/100)**2)
 7 
 8 
 9 
10 sns.distplot(erg_distance.loc[erg_distance<400])

 

 

 

 

1 erg_died_of.loc[(erg_distance > 800)&(erg_distance < 1500), 'killed_by'].value_counts()[:10].plot.bar(rot=30)
2 plt.xlabel("狙击的武器", fontsize=14)
3 plt.ylabel("被狙击的人数", fontsize=14)
4 plt.title('狙击武器跟击杀人数的统计(绝地海岛艾伦格)', fontsize=14)
5 plt.yticks(fontsize=12)

 

 

 

 

1 mrm_died_of.loc[(mrm_distance > 800)&(mrm_distance < 1000), 'killed_by'].value_counts()[:10].plot.bar(rot=30)
2 plt.xlabel("狙击的武器", fontsize=14)
3 plt.ylabel("被狙击的人数", fontsize=14)
4 plt.title('狙击武器跟击杀人数的统计(热情沙漠米拉玛)', fontsize=14)
5 plt.yticks(fontsize=12)

 

 

 

 近战适合使用什么武器?

1 erg_died_of.loc[erg_distance<10, 'killed_by'].value_counts()[:10].plot.bar(rot=30)
2 plt.xlabel("近战武器", fontsize=14)
3 plt.ylabel("被击杀的人数", fontsize=14)
4 plt.title('近战武器跟击杀人数的统计(绝地海岛艾伦格)', fontsize=14)
5 plt.yticks(fontsize=12)

 

 

 

 

1 mrm_died_of.loc[mrm_distance<10, 'killed_by'].value_counts()[:10].plot.bar(rot=30)
2 plt.xlabel("近战武器", fontsize=14)
3 plt.ylabel("被击杀的人数", fontsize=14)
4 plt.title('近战武器武器跟击杀人数的统计(热情沙漠米拉玛)', fontsize=14)
5 plt.yticks(fontsize=12)

 

 

 

 Top10武器在各距离下的击杀百分比

  1 erg_died_of['erg_dist'] = erg_distance
  2 erg_died_of = erg_died_of.loc[erg_died_of['erg_dist']<800, :]
  3 top_weapons_erg = list(erg_died_of['killed_by'].value_counts()[:10].index)
  4 top_weapon_kills = erg_died_of[np.in1d(erg_died_of['killed_by'], top_weapons_erg)].copy()
  5 top_weapon_kills['bin'] = pd.cut(top_weapon_kills['erg_dist'], np.arange(0, 800, 10), include_lowest=True, labels=False)
  6 top_weapon_kills_wide = top_weapon_kills.groupby(['killed_by', 'bin']).size().unstack(fill_value=0).transpose()
  7 
  8 
  9 
 10 top_weapon_kills_wide = top_weapon_kills_wide.div(top_weapon_kills_wide.sum(axis=1), axis=0)
 11 
 12 
 13 
 14 from bokeh.models.tools import HoverTool
 15 from bokeh.palettes import brewer
 16 from bokeh.plotting import figure, show, output_notebook
 17 from bokeh.models.sources import ColumnDataSource
 18 
 19 def stacked(df):
 20 df_top = df.cumsum(axis=1)
 21 df_bottom = df_top.shift(axis=1).fillna(0)[::-1]
 22 df_stack = pd.concat([df_bottom, df_top], ignore_index=True)
 23 return df_stack
 24 
 25 hover = HoverTool(
 26 tooltips=[
 27 ("index", "$index"),
 28 ("weapon", "@weapon"),
 29 ("(x,y)", "($x, $y)")
 30 ],
 31 point_policy='follow_mouse'
 32 )
 33 
 34 areas = stacked(top_weapon_kills_wide)
 35 
 36 colors = brewer['Spectral'][areas.shape[1]]
 37 x2 = np.hstack((top_weapon_kills_wide.index[::-1],
 38 top_weapon_kills_wide.index)) /0.095
 39 
 40 TOOLS="pan,wheel_zoom,box_zoom,reset,previewsave"
 41 output_notebook()
 42 p = figure(x_range=(1, 800), y_range=(0, 1), tools=[TOOLS, hover], plot_width=800)
 43 p.grid.minor_grid_line_color = '#eeeeee'
 44 
 45 source = ColumnDataSource(data={
 46 'x': [x2] * areas.shape[1],
 47 'y': [areas[c].values for c in areas],
 48 'weapon': list(top_weapon_kills_wide.columns),
 49 'color': colors
 50 })
 51 
 52 p.patches('x', 'y', source=source, legend="weapon",
 53 color='color', alpha=0.8, line_color=None)
 54 p.title.text = "Top10武器在各距离下的击杀百分比(绝地海岛艾伦格)"
 55 p.xaxis.axis_label = "击杀距离(0-800米)"
 56 p.yaxis.axis_label = "百分比"
 57 
 58 show(p)
 59 
 60 
 61 
 62 mrm_died_of['erg_dist'] = mrm_distance
 63 mrm_died_of = mrm_died_of.loc[mrm_died_of['erg_dist']<800, :]
 64 top_weapons_erg = list(mrm_died_of['killed_by'].value_counts()[:10].index)
 65 top_weapon_kills = mrm_died_of[np.in1d(mrm_died_of['killed_by'], top_weapons_erg)].copy()
 66 top_weapon_kills['bin'] = pd.cut(top_weapon_kills['erg_dist'], np.arange(0, 800, 10), include_lowest=True, labels=False)
 67 top_weapon_kills_wide = top_weapon_kills.groupby(['killed_by', 'bin']).size().unstack(fill_value=0).transpose()
 68 
 69 top_weapon_kills_wide = top_weapon_kills_wide.div(top_weapon_kills_wide.sum(axis=1), axis=0)
 70 
 71 
 72 
 73 def stacked(df):
 74 df_top = df.cumsum(axis=1)
 75 df_bottom = df_top.shift(axis=1).fillna(0)[::-1]
 76 df_stack = pd.concat([df_bottom, df_top], ignore_index=True)
 77 return df_stack
 78 
 79 hover = HoverTool(
 80 tooltips=[
 81 ("index", "$index"),
 82 ("weapon", "@weapon"),
 83 ("(x,y)", "($x, $y)")
 84 ],
 85 point_policy='follow_mouse'
 86 )
 87 
 88 areas = stacked(top_weapon_kills_wide)
 89 
 90 colors = brewer['Spectral'][areas.shape[1]]
 91 x2 = np.hstack((top_weapon_kills_wide.index[::-1],
 92 top_weapon_kills_wide.index)) /0.095
 93 
 94 TOOLS="pan,wheel_zoom,box_zoom,reset,previewsave"
 95 output_notebook()
 96 p = figure(x_range=(1, 800), y_range=(0, 1), tools=[TOOLS, hover], plot_width=800)
 97 p.grid.minor_grid_line_color = '#eeeeee'
 98 
 99 source = ColumnDataSource(data={
100 'x': [x2] * areas.shape[1],
101 'y': [areas[c].values for c in areas],
102 'weapon': list(top_weapon_kills_wide.columns),
103 'color': colors
104 })
105 
106 p.patches('x', 'y', source=source, legend="weapon",
107 color='color', alpha=0.8, line_color=None)
108 p.title.text = "Top10武器在各距离下的击杀百分比(热情沙漠米拉玛)"
109 p.xaxis.axis_label = "击杀距离(0-800米)"
110 p.yaxis.axis_label = "击杀百分比"
111 
112 show(p)

 

 

自己把自己干倒的方式与人数

 

1 death1.head()

 

 

 

1  kill_by_self = death1.loc[death1['killer_name']==death1['victim_name'], "killed_by"]
2 
3 kill_by_self.value_counts()[:10].plot.barh()
4 plt.xlabel("自毙的人数", fontsize=14)
5 plt.ylabel("自毙的方式", fontsize=14)
6 plt.title('自己把自己干倒的方式与人数', fontsize=14)
7 plt.yticks(fontsize=12)

 

 

 

 

1 # 自己把自己干倒的人数场均百分比
2 kill_by_self.shape[0]/death1.shape[0]*100

 

 

 

 完整代码:

  1 import pandas as pd
  2 import numpy as np
  3 import matplotlib.pyplot as plt
  4 import seaborn as sns
  5 %matplotlib inline
  6 plt.rcParams['font.sans-serif'] = ['SimHei'] # 指定默认字体
  7 plt.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题
  8 
  9 # 使用pandas读取数据
 10 agg1 = pd.read_csv('/Users/apple/Desktop/pubg/aggregate/agg_match_stats_1.csv')
 11 
 12 # 探索数据结构
 13 agg1.head()
 14 
 15 # 总共有13844275行玩家数据,15列
 16 agg1.shape
 17 
 18 agg1.columns
 19 
 20 agg1.info()
 21 
 22 # 丢弃重复数据
 23 agg1.drop_duplicates(inplace=True)
 24 
 25 agg1.loc[1]
 26 
 27 # 添加是否成功吃鸡列
 28 agg1['won'] = agg1['team_placement'] == 1
 29 
 30 # 添加是否搭乘过车辆列
 31 agg1['drove'] = agg1['player_dist_ride'] != 0
 32 
 33 agg1.loc[agg1['player_kills'] < 40, ['player_kills', 'won']].groupby('player_kills').won.mean().plot.bar(figsize=(15,6), rot=0)
 34 plt.xlabel('击杀人数', fontsize=14)
 35 plt.ylabel("吃鸡概率", fontsize=14)
 36 plt.title('击杀人数与吃鸡概率的关系', fontsize=14)
 37 
 38 agg1.groupby('party_size').player_kills.mean()
 39 
 40 g = sns.FacetGrid(agg1.loc[agg1['player_kills']<=10, ['party_size', 'player_kills']], row="party_size", size=4, aspect=2)
 41 g = g.map(sns.countplot, "player_kills")
 42 
 43 agg1.loc[agg1['party_size']!=1, ['player_assists', 'won']].groupby('player_assists').won.mean().plot.bar(figsize=(15,6), rot=0)
 44 plt.xlabel('助攻次数', fontsize=14)
 45 plt.ylabel("吃鸡概率", fontsize=14)
 46 plt.title('助攻次数与吃鸡概率的关系', fontsize=14)
 47 
 48 agg1.groupby('drove').won.mean().plot.barh(figsize=(6,3))
 49 plt.xlabel("吃鸡概率", fontsize=14)
 50 plt.ylabel("是否搭乘过车辆", fontsize=14)
 51 plt.title('搭乘车辆与吃鸡概率的关系', fontsize=14)
 52 plt.yticks([1,0],['',''])
 53 
 54 dist_ride = agg1.loc[agg1['player_dist_ride']<12000, ['player_dist_ride', 'won']]
 55 
 56 labels=["0-1k", "1-2k", "2-3k", "3-4k","4-5k", "5-6k", "6-7k", "7-8k", "8-9k", "9-10k", "10-11k", "11-12k"]
 57 dist_ride['drove_cut'] = pd.cut(dist_ride['player_dist_ride'], 12, labels=labels)
 58 
 59 dist_ride.groupby('drove_cut').won.mean().plot.bar(rot=60, figsize=(8,4))
 60 plt.xlabel("搭乘车辆里程", fontsize=14)
 61 plt.ylabel("吃鸡概率", fontsize=14)
 62 plt.title('搭乘车辆里程与吃鸡概率的关系', fontsize=14)
 63 
 64 match_unique = agg1.loc[agg1['party_size'] == 1, 'match_id'].unique()
 65 
 66 # 先把玩家被击杀的数据导入进来并探索数据
 67 death1 = pd.read_csv('/Users/apple/Desktop/pubg/deaths/kill_match_stats_final_1.csv')
 68 
 69 death1.head()
 70 
 71 death1.info()
 72 
 73 death1.shape
 74 
 75 death1_solo = death1[death1['match_id'].isin(match_unique)]
 76 
 77 death1_solo.info()
 78 
 79 # 只统计单人模式,筛选存活不超过180秒的玩家数据
 80 death_180_seconds_erg = death1_solo.loc[(death1_solo['map'] == 'ERANGEL')&(death1_solo['time'] < 180)&(death1_solo['victim_position_x']>0), :].dropna()
 81 death_180_seconds_mrm = death1_solo.loc[(death1_solo['map'] == 'MIRAMAR')&(death1_solo['time'] < 180)&(death1_solo['victim_position_x']>0), :].dropna()
 82 
 83 death_180_seconds_erg.shape
 84 
 85 death_180_seconds_mrm.shape
 86 
 87 # 选择存活不过180秒的玩家死亡位置
 88 data_erg = death_180_seconds_erg[['victim_position_x', 'victim_position_y']].values
 89 data_mrm = death_180_seconds_mrm[['victim_position_x', 'victim_position_y']].values
 90 
 91 # 重新scale玩家位置
 92 data_erg = data_erg*4096/800000
 93 data_mrm = data_mrm*1000/800000
 94 
 95 from scipy.ndimage.filters import gaussian_filter
 96 import matplotlib.cm as cm
 97 from matplotlib.colors import Normalize
 98 from scipy.misc.pilutil import imread
 99 
100 from scipy.ndimage.filters import gaussian_filter
101 import matplotlib.cm as cm
102 from matplotlib.colors import Normalize
103 
104 def heatmap(x, y, s, bins=100):
105     heatmap, xedges, yedges = np.histogram2d(x, y, bins=bins)
106     heatmap = gaussian_filter(heatmap, sigma=s)
107 
108     extent = [xedges[0], xedges[-1], yedges[0], yedges[-1]]
109     return heatmap.T, extent
110 
111 bg = imread('/Users/apple/Desktop/pubg/erangel.jpg')
112 hmap, extent = heatmap(data_erg[:,0], data_erg[:,1], 4.5)
113 alphas = np.clip(Normalize(0, hmap.max(), clip=True)(hmap)*4.5, 0.0, 1.)
114 colors = Normalize(0, hmap.max(), clip=True)(hmap)
115 colors = cm.Reds(colors)
116 colors[..., -1] = alphas
117 
118 fig, ax = plt.subplots(figsize=(24,24))
119 ax.set_xlim(0, 4096); ax.set_ylim(0, 4096)
120 ax.imshow(bg)
121 ax.imshow(colors, extent=extent, origin='lower', cmap=cm.Reds, alpha=0.9)
122 plt.gca().invert_yaxis()
123 
124 bg = imread('/Users/apple/Desktop/pubg/miramar.jpg')
125 hmap, extent = heatmap(data_mrm[:,0], data_mrm[:,1], 4)
126 alphas = np.clip(Normalize(0, hmap.max(), clip=True)(hmap)*4, 0.0, 1.)
127 colors = Normalize(0, hmap.max(), clip=True)(hmap)
128 colors = cm.Reds(colors)
129 colors[..., -1] = alphas
130 
131 fig, ax = plt.subplots(figsize=(24,24))
132 ax.set_xlim(0, 1000); ax.set_ylim(0, 1000)
133 ax.imshow(bg)
134 ax.imshow(colors, extent=extent, origin='lower', cmap=cm.Reds, alpha=0.9)
135 #plt.scatter(plot_data_mr[:,0], plot_data_mr[:,1])
136 plt.gca().invert_yaxis()
137 
138 death_final_circle_erg = death1_solo.loc[(death1_solo['map'] == 'ERANGEL')&(death1_solo['victim_placement'] == 2)&(death1_solo['victim_position_x']>0)&(death1_solo['killer_position_x']>0), :].dropna()
139 death_final_circle_mrm = death1_solo.loc[(death1_solo['map'] == 'MIRAMAR')&(death1_solo['victim_placement'] == 2)&(death1_solo['victim_position_x']>0)&(death1_solo['killer_position_x']>0), :].dropna()
140 
141 print(death_final_circle_erg.shape)
142 print(death_final_circle_mrm.shape)
143 
144 final_circle_erg = np.vstack([death_final_circle_erg[['victim_position_x', 'victim_position_y']].values, 
145                                     death_final_circle_erg[['killer_position_x', 'killer_position_y']].values])*4096/800000
146 final_circle_mrm = np.vstack([death_final_circle_mrm[['victim_position_x', 'victim_position_y']].values,
147                                     death_final_circle_mrm[['killer_position_x', 'killer_position_y']].values])*1000/800000
148 
149 bg = imread('/Users/apple/Desktop/pubg/erangel.jpg')
150 hmap, extent = heatmap(final_circle_erg[:,0], final_circle_erg[:,1], 1.5)
151 alphas = np.clip(Normalize(0, hmap.max(), clip=True)(hmap)*1.5, 0.0, 1.)
152 colors = Normalize(0, hmap.max(), clip=True)(hmap)
153 colors = cm.Reds(colors)
154 colors[..., -1] = alphas
155 
156 fig, ax = plt.subplots(figsize=(24,24))
157 ax.set_xlim(0, 4096); ax.set_ylim(0, 4096)
158 ax.imshow(bg)
159 ax.imshow(colors, extent=extent, origin='lower', cmap=cm.Reds, alpha=0.9)
160 #plt.scatter(plot_data_er[:,0], plot_data_er[:,1])
161 plt.gca().invert_yaxis()
162 
163 bg = imread('/Users/apple/Desktop/pubg/miramar.jpg')
164 hmap, extent = heatmap(final_circle_mrm[:,0], final_circle_mrm[:,1], 1.5)
165 alphas = np.clip(Normalize(0, hmap.max(), clip=True)(hmap)*1.5, 0.0, 1.)
166 colors = Normalize(0, hmap.max(), clip=True)(hmap)
167 colors = cm.Reds(colors)
168 colors[..., -1] = alphas
169 
170 fig, ax = plt.subplots(figsize=(24,24))
171 ax.set_xlim(0, 1000); ax.set_ylim(0, 1000)
172 ax.imshow(bg)
173 ax.imshow(colors, extent=extent, origin='lower', cmap=cm.Reds, alpha=0.9)
174 #plt.scatter(plot_data_mr[:,0], plot_data_mr[:,1])
175 plt.gca().invert_yaxis()
176 
177 erg_died_of = death1.loc[(death1['map']=='ERANGEL')&(death1['killer_position_x']>0)&(death1['victim_position_x']>0)&(death1['killed_by']!='Down and Out'),:]
178 mrm_died_of = death1.loc[(death1['map']=='MIRAMAR')&(death1['killer_position_x']>0)&(death1['victim_position_x']>0)&(death1['killed_by']!='Down and Out'),:]
179 
180 print(erg_died_of.shape)
181 print(mrm_died_of.shape)
182 
183 erg_died_of['killed_by'].value_counts()[:10].plot.barh(figsize=(10,5))
184 plt.xlabel("被击杀人数", fontsize=14)
185 plt.ylabel("击杀的武器", fontsize=14)
186 plt.title('武器跟击杀人数的统计(绝地海岛艾伦格)', fontsize=14)
187 plt.yticks(fontsize=12)
188 
189 mrm_died_of['killed_by'].value_counts()[:10].plot.barh(figsize=(10,5))
190 plt.xlabel("被击杀人数", fontsize=14)
191 plt.ylabel("击杀的武器", fontsize=14)
192 plt.title('武器跟击杀人数的统计(热情沙漠米拉玛)', fontsize=14)
193 plt.yticks(fontsize=12)
194 
195 # 把位置信息转换成距离,以“米”为单位
196 erg_distance = np.sqrt(((erg_died_of['killer_position_x']-erg_died_of['victim_position_x'])/100)**2 + ((erg_died_of['killer_position_y']-erg_died_of['victim_position_y'])/100)**2)
197 
198 mrm_distance = np.sqrt(((mrm_died_of['killer_position_x']-mrm_died_of['victim_position_x'])/100)**2 + ((mrm_died_of['killer_position_y']-mrm_died_of['victim_position_y'])/100)**2)
199 
200 sns.distplot(erg_distance.loc[erg_distance<400])
201 
202 erg_died_of.loc[(erg_distance > 800)&(erg_distance < 1500), 'killed_by'].value_counts()[:10].plot.bar(rot=30)
203 plt.xlabel("狙击的武器", fontsize=14)
204 plt.ylabel("被狙击的人数", fontsize=14)
205 plt.title('狙击武器跟击杀人数的统计(绝地海岛艾伦格)', fontsize=14)
206 plt.yticks(fontsize=12)
207 
208 mrm_died_of.loc[(mrm_distance > 800)&(mrm_distance < 1000), 'killed_by'].value_counts()[:10].plot.bar(rot=30)
209 plt.xlabel("狙击的武器", fontsize=14)
210 plt.ylabel("被狙击的人数", fontsize=14)
211 plt.title('狙击武器跟击杀人数的统计(热情沙漠米拉玛)', fontsize=14)
212 plt.yticks(fontsize=12)
213 
214 erg_died_of.loc[erg_distance<10, 'killed_by'].value_counts()[:10].plot.bar(rot=30)
215 plt.xlabel("近战武器", fontsize=14)
216 plt.ylabel("被击杀的人数", fontsize=14)
217 plt.title('近战武器跟击杀人数的统计(绝地海岛艾伦格)', fontsize=14)
218 plt.yticks(fontsize=12)
219 
220 mrm_died_of.loc[mrm_distance<10, 'killed_by'].value_counts()[:10].plot.bar(rot=30)
221 plt.xlabel("近战武器", fontsize=14)
222 plt.ylabel("被击杀的人数", fontsize=14)
223 plt.title('近战武器武器跟击杀人数的统计(热情沙漠米拉玛)', fontsize=14)
224 plt.yticks(fontsize=12)
225 
226 erg_died_of['erg_dist'] = erg_distance
227 erg_died_of = erg_died_of.loc[erg_died_of['erg_dist']<800, :]
228 top_weapons_erg = list(erg_died_of['killed_by'].value_counts()[:10].index)
229 top_weapon_kills = erg_died_of[np.in1d(erg_died_of['killed_by'], top_weapons_erg)].copy()
230 top_weapon_kills['bin'] = pd.cut(top_weapon_kills['erg_dist'], np.arange(0, 800, 10), include_lowest=True, labels=False)
231 top_weapon_kills_wide = top_weapon_kills.groupby(['killed_by', 'bin']).size().unstack(fill_value=0).transpose()
232 
233 top_weapon_kills_wide = top_weapon_kills_wide.div(top_weapon_kills_wide.sum(axis=1), axis=0)
234 
235 from bokeh.models.tools import HoverTool
236 from bokeh.palettes import brewer
237 from bokeh.plotting import figure, show, output_notebook
238 from bokeh.models.sources import ColumnDataSource
239 
240 def  stacked(df):
241     df_top = df.cumsum(axis=1)
242     df_bottom = df_top.shift(axis=1).fillna(0)[::-1]
243     df_stack = pd.concat([df_bottom, df_top], ignore_index=True)
244     return df_stack
245 
246 hover = HoverTool(
247     tooltips=[
248             ("index", "$index"),
249             ("weapon", "@weapon"),
250             ("(x,y)", "($x, $y)")
251         ],
252     point_policy='follow_mouse'
253     )
254 
255 areas = stacked(top_weapon_kills_wide)
256 
257 colors = brewer['Spectral'][areas.shape[1]]
258 x2 = np.hstack((top_weapon_kills_wide.index[::-1],
259                 top_weapon_kills_wide.index)) /0.095
260 
261 TOOLS="pan,wheel_zoom,box_zoom,reset,previewsave"
262 output_notebook()
263 p = figure(x_range=(1, 800), y_range=(0, 1), tools=[TOOLS, hover], plot_width=800)
264 p.grid.minor_grid_line_color = '#eeeeee'
265 
266 source = ColumnDataSource(data={
267     'x': [x2] * areas.shape[1],
268     'y': [areas[c].values for c in areas],
269     'weapon': list(top_weapon_kills_wide.columns),
270     'color': colors
271 })
272 
273 p.patches('x', 'y', source=source, legend="weapon",
274           color='color', alpha=0.8, line_color=None)
275 p.title.text = "Top10武器在各距离下的击杀百分比(绝地海岛艾伦格)"
276 p.xaxis.axis_label = "击杀距离(0-800米)"
277 p.yaxis.axis_label = "百分比"
278 
279 show(p)
280 
281 mrm_died_of['erg_dist'] = mrm_distance
282 mrm_died_of = mrm_died_of.loc[mrm_died_of['erg_dist']<800, :]
283 top_weapons_erg = list(mrm_died_of['killed_by'].value_counts()[:10].index)
284 top_weapon_kills = mrm_died_of[np.in1d(mrm_died_of['killed_by'], top_weapons_erg)].copy()
285 top_weapon_kills['bin'] = pd.cut(top_weapon_kills['erg_dist'], np.arange(0, 800, 10), include_lowest=True, labels=False)
286 top_weapon_kills_wide = top_weapon_kills.groupby(['killed_by', 'bin']).size().unstack(fill_value=0).transpose()
287 
288 top_weapon_kills_wide = top_weapon_kills_wide.div(top_weapon_kills_wide.sum(axis=1), axis=0)
289 def  stacked(df):
290     df_top = df.cumsum(axis=1)
291     df_bottom = df_top.shift(axis=1).fillna(0)[::-1]
292     df_stack = pd.concat([df_bottom, df_top], ignore_index=True)
293     return df_stack
294 
295 hover = HoverTool(
296     tooltips=[
297             ("index", "$index"),
298             ("weapon", "@weapon"),
299             ("(x,y)", "($x, $y)")
300         ],
301     point_policy='follow_mouse'
302     )
303 
304 areas = stacked(top_weapon_kills_wide)
305 
306 colors = brewer['Spectral'][areas.shape[1]]
307 x2 = np.hstack((top_weapon_kills_wide.index[::-1],
308                 top_weapon_kills_wide.index)) /0.095
309 
310 TOOLS="pan,wheel_zoom,box_zoom,reset,previewsave"
311 output_notebook()
312 p = figure(x_range=(1, 800), y_range=(0, 1), tools=[TOOLS, hover], plot_width=800)
313 p.grid.minor_grid_line_color = '#eeeeee'
314 
315 source = ColumnDataSource(data={
316     'x': [x2] * areas.shape[1],
317     'y': [areas[c].values for c in areas],
318     'weapon': list(top_weapon_kills_wide.columns),
319     'color': colors
320 })
321 
322 p.patches('x', 'y', source=source, legend="weapon",
323           color='color', alpha=0.8, line_color=None)
324 p.title.text = "Top10武器在各距离下的击杀百分比(热情沙漠米拉玛)"
325 p.xaxis.axis_label = "击杀距离(0-800米)"
326 p.yaxis.axis_label = "击杀百分比"
327 
328 show(p)
329 
330 death1.head()
331 
332 kill_by_self = death1.loc[death1['killer_name']==death1['victim_name'], "killed_by"]
333 
334 kill_by_self.value_counts()[:10].plot.barh()
335 plt.xlabel("自毙的人数", fontsize=14)
336 plt.ylabel("自毙的方式", fontsize=14)
337 plt.title('自己把自己干倒的方式与人数', fontsize=14)
338 plt.yticks(fontsize=12)
339 
340 # 自己把自己干倒的人数场均百分比
341 kill_by_self.shape[0]/death1.shape[0]*100

五,总结

  使用matplotlib库做出游戏中的热感应图,是本次程序设计最大的收获,已经达到预期目标对绝地求生比赛数据集分析和可视化。

 

posted @ 2021-06-23 22:44  fengyy  阅读(959)  评论(1编辑  收藏  举报