游戏数据活动复盘分析

2020-10-14  本文已影响0人  SongSir1

项目介绍

数据集内容为某游戏82万条玩家信息,其中包含108个字段,现需要展开数据内容对用户进行分析

项目过程

  1. 数据处理(包含字段清洗去重、筛选字段等)
  2. 新增用户分析(从玩家数量、付费玩家占比、每日新增玩家数展开分析)
  3. 玩家活跃度分析(从不同用户在线时长、分布特征展开分析)
  4. 玩家付费情况分析(从PUR,ARPPU,ARPU等关键指标得出的情况来展开分析)
  5. 付费玩家习惯分析(从不同玩家的pvp、pve这两个指标得出的情况来展开分析)

0. 模块导入

import pandas as pd
import numpy as np
import sqlalchemy
import matplotlib.pyplot as plt
# pyecharts 绘图包
import pyecharts.options as opts
from pyecharts.charts import Bar, Line, Boxplot, Pie

可以通过pip install pyecharts==1.7.1进行安装

1. 数据处理

# 数据大小
data.shape

# 判断空值数量
data.isnull().sum().sum()

# 判断重复值
data.drop_duplicates("user_id").shape

输出结果

(828934, 108)
0
(828934, 108)

数据有828934条,无空值、无重复值,比较干净
但该数据集有108条字段,目前对于分析暂时没用,仅提取以下字段:

data = data[["user_id","pay_price","register_time","avg_online_minutes","pvp_battle_count","pvp_lanch_count","pvp_win_count","pve_battle_count","pve_lanch_count","pve_win_count"]]

因为从sql数据库提取的字段,全部都为object格式,现对其进行转换

# 转换pry_price数据类型为float
data = data.astype({"pay_price":"float","avg_online_minutes":"float"})
data.loc[:,"avg_online_minutes":] = data.loc[:,"avg_online_minutes":].astype("float")

最终数据如下:


2. 新增用户分析

2.1 玩家数量

# 新增玩家数
new_all = data.user_id.count()
# 新增付费玩家数
new_pay = data.query("pay_price > 0").user_id.count()
# 付费玩家占比
new_pay / new_all

out:

# pyecharts绘图
a = [["非付费玩家",int(new_all-new_pay)], ["付费玩家", int(new_pay)]]
pie = (Pie()
       .add("",a,label_opts = opts.LabelOpts(formatter="{b}:{d}%",is_show = True))
       .set_global_opts(title_opts=opts.TitleOpts(title = "玩家占比", subtitle="对象均为近期新增玩家"),
        legend_opts=opts.LegendOpts(pos_left="right"))
           )
pie.render_notebook()

2.2 新增趋势

按日期将每日新增的玩家总数与付费玩家进行聚合

# 增加日期字段
data["register_day"] = data["register_time"].str[:11]
# 按日聚合
grouped_day = data.groupby("register_day")

# 绘制趋势图
# 日期
x = list(grouped_day.user_id.count().index)
# 新增总玩家
y1 = list(grouped_day.user_id.count().values)
# 新增付费玩家
y2 = list(data.query("pay_price > 0").groupby("register_day").user_id.count().values)

# pyecharts堆叠折线图绘制
line =(Line()
      .add_xaxis(x)
      .add_yaxis("每日新增总玩家数",[int(i) for i in y1])
      .extend_axis(  # 为line增加一个新的维度,添加次坐标轴
          yaxis=opts.AxisOpts(  # 增加一个y次坐标轴  (因为是yaxis = ...)
              axislabel_opts=opts.LabelOpts(formatter="{value}"), interval=300,max_ = 2100))  #次坐标轴 标签为value值,间隔300,最大值2100
      .set_global_opts(
      xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(rotate = 45)),
      yaxis_opts=opts.AxisOpts(name = "新增数(单位/人)"),
      title_opts = opts.TitleOpts(title="每日新增趋势"))
      )
line2 = Line().add_xaxis(x).add_yaxis("每日新增付费玩家",[int(i) for i in y2], yaxis_index=1)  # 注意需要加 yaxis_index = 1 指定坐标轴维度
line.overlap(line2)  # 表示将line2绘制在line上
line.render_notebook()

结果得知:

3. 玩家活跃度分析

3.1 玩家时长对比

1. 对比全体玩家和付费玩家的平均游戏时长

all_avg_minutes = data.avg_online_minutes.mean()
pay_avg_minutes = data.query("pay_price > 0").avg_online_minutes.mean()
print("全部玩家平均在线时长:",all_avg_minutes)
print("付费玩家平均在线时长:",pay_avg_minutes)
# 绘图
bar = (
    Bar()
    .add_xaxis(["全体玩家","付费玩家"])
    .add_yaxis("",['%.2f'% i for i in [all_avg_minutes,pay_avg_minutes]])
    .set_global_opts(
        title_opts=opts.TitleOpts(title="玩家平均在线时长对比"),
        yaxis_opts=opts.AxisOpts(name = "时长(单位/分钟)"))
    .set_series_opts(label_opts=opts.LabelOpts(is_show=True,formatter = "{c}分钟"))
        )
bar.render_notebook()
#绘制箱线图
value = [list(data.avg_online_minutes),list(data.query("pay_price > 0").avg_online_minutes)]

c = Boxplot()
c.add_xaxis(["全体玩家", "付费玩家"])
c.add_yaxis("", c.prepare_data(value))
c.set_global_opts(title_opts=opts.TitleOpts(title="全体玩家与付费玩家在线时长对比"))
c.render_notebook()

直方图结果:

箱线图结果:

2. 绘制在线时长分布直方图

plt.figure(figsize=(16,6))

plt.rcParams['font.size']=14
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号

# 全体玩家分布  # 去掉极值影响 取时长小于400分钟的
plt.subplot(1,2,1)
data.query("avg_online_minutes < 400").avg_online_minutes.plot(kind='hist',alpha=0.7,bins = 20)
plt.title("全体玩家")
plt.ylabel("频数",fontsize = 16)

# 付费玩家分布
plt.subplot(1,2,2)
data.query("pay_price > 0").avg_online_minutes.plot(kind='hist',alpha=0.7,bins = 20)
plt.title("付费玩家")
plt.ylabel("频数",fontsize = 16)

plt.suptitle("玩家游戏时长分布直方图", fontsize = 22)
plt.show()

3.2 游戏时长与消费金额散点分布

plt.scatter(data.query("pay_price > 0").avg_online_minutes,data.query("pay_price > 0").pay_price)
plt.xlabel("游戏时长(单位:分钟)")
plt.ylabel("充值金额(单位:元)")
plt.title("游戏时长与充值金额散点图")
plt.show()

4. 玩家付费情况分析

关键指标

4.1 指标计算

# 总收入
GMV = data.pay_price.sum()
# 活跃用户 
AU = data.query("avg_online_minutes >= 15").user_id.count()
# 活跃付费用户
APA = data.query("avg_online_minutes >= 15 and pay_price > 0").user_id.count()
# 每个活跃玩家的收入
ARPU = GMV / AU
# 每个活跃付费玩家收入
ARPPU = GMV / APA
# 付费率
PUR = APA / AU
# 活跃用户占比
AU/data.user_id.count()
plt.figure(figsize=(16,6))

# AU 和 APA 对比
plt.subplot(1,2,1)
plt.bar(["AU", "APA"],[AU, APA])
plt.title("AU 和 APA 对比")

# 付费玩家分布
plt.subplot(1,2,2)
plt.bar(["ARPU", "ARPPU"],[ARPU, ARPPU])
plt.title("ARPU 和 ARPPU 对比")
plt.show()
from pyecharts.charts import Gauge
gauge = (
    Gauge(init_opts=opts.InitOpts(width="900px", height="400px"))
    .add("", data_pair=[["玩家付费率:PUR", round(PUR*100,2)]])
    .set_global_opts(
        legend_opts=opts.LegendOpts(is_show=False),
        tooltip_opts=opts.TooltipOpts(is_show=True, formatter="{c}%"),
    )
)
gauge.render_notebook()

注意:大R玩家,可以表示为游戏充值金额非常大的人,需要重点维持。

5. 玩家游戏习惯分析

先从数据表中将AU玩家与APA玩家进行筛选

au_data = data.query("avg_online_minutes >= 15")
apa_data = data.query("avg_online_minutes >= 15 and pay_price > 0")

计算AU、APA玩家的PVP情况

# AU 玩家平均PVP次数
au_data.pvp_battle_count.mean()
# AU 玩家主动发起的概率
au_data.pvp_lanch_count.sum() / au_data.pvp_battle_count.sum()
# AU 玩家胜率
au_data.pvp_win_count.sum() / au_data.pvp_battle_count.sum()
# APA 玩家平均的PVP次数
apa_data.pvp_battle_count.mean()
# AU 玩家主动发起的概率
apa_data.pvp_lanch_count.sum() / apa_data.pvp_battle_count.sum()
# AU 玩家胜率
apa_data.pvp_win_count.sum() / apa_data.pvp_battle_count.sum()

# 制作DataFrame 
d = [[15.16, 0.5688, 0.5322],[27.3, 0.6553, 0.6872]]
pvp_data = pd.DataFrame(d,index = {"AU","APA"},columns = {"次数","主动发起概率","胜率"})

计算AU、APA玩家的PVE情况

# AU 玩家平均PVE次数
au_data.pve_battle_count.mean()
# AU 玩家主动发起的概率
au_data.pve_lanch_count.sum() / au_data.pve_battle_count.sum()
# AU 玩家胜率
au_data.pve_win_count.sum() / au_data.pve_battle_count.sum()
# APA 玩家平均的PVE次数
apa_data.pve_battle_count.mean()
# AU 玩家主动发起的概率
apa_data.pve_lanch_count.sum() / apa_data.pve_battle_count.sum()
# AU 玩家胜率
apa_data.pve_win_count.sum() / apa_data.pve_battle_count.sum()

# DataFrame
d = [[28.15, 0.9967, 0.9041],[51.96, 0.9957, 0.911]]
pve_data = pd.DataFrame(d,index = {"AU","APA"},columns = {"次数","主动发起概率","胜率"})
PVP PVE

绘制pyecharts图形

bar = (Bar()
      .add_xaxis(["平均PVP次数","平均PVE次数"])
      .add_yaxis("AU玩家",[pvp_data.iloc[1][0],pve_data.iloc[1][0]])
      .add_yaxis("APA玩家",[pvp_data.iloc[0][0],pve_data.iloc[0][0]])
      .set_global_opts(
        title_opts=opts.TitleOpts(title="AU、APA玩家PVP、PVE对比"),
        yaxis_opts=opts.AxisOpts(name = "次数"),
        legend_opts=opts.LegendOpts(pos_left="right"))
      
      )
bar.render_notebook()
bar = (Bar()
      .add_xaxis(["主动PVP概率","PVP胜率","主动PVE概率","PVE胜率"])
      .add_yaxis("AU玩家",[pvp_data.iloc[1][1],pvp_data.iloc[1][2],pve_data.iloc[1][1],pve_data.iloc[1][2]])
      .add_yaxis("APA玩家",[pvp_data.iloc[0][1],pvp_data.iloc[0][2],pve_data.iloc[0][1],pve_data.iloc[0][2]])
      .set_global_opts(
        title_opts=opts.TitleOpts(title="AU、APA玩家PVP、PVE对比"),
        yaxis_opts=opts.AxisOpts(name = "概率"),
        legend_opts=opts.LegendOpts(pos_left="right"))
      
      )
bar.render_notebook()

在PVP活动中,APA玩家主动发起进攻的概率和胜利的概率要明显高于AU玩家,在享受游戏对战乐趣的过程中,往往更能够收获胜利。

结论

1.新增用户分析
2.玩家活跃度分析
3.玩家付费情况分析
4.付费玩家习惯分析
上一篇 下一篇

猜你喜欢

热点阅读