游戏数据活动复盘分析

项目介绍

数据集内容为某游戏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
  • pyecharts 绘图包版本为1.7.1

可以通过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条字段,目前对于分析暂时没用,仅提取以下字段:

  • user_id : 玩家ID
  • pay_price:付费金额
  • register_time:玩家注册时间
  • avg_online_minutes:在线时长
  • pvp_battle_count:玩家PVP次数
  • pvp_lanch_count:主动发起的PVP次数
  • pvp_win_count:PVP胜利次数
  • pve_battle_count:pve次数
  • pve_lanch_count:主动PVE次数
  • pve_win_count:pve胜利次数
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:

  • 新增玩家数量:82,8934
  • 新增付费玩家:19,549
  • 付费玩家占比:0.02358
# 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()
  • 近期该游戏新增付费玩家数有19549,新增总玩家828934,付费玩家占比仅2.36%,消费率极低。

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

结果得知:

  • 总体新增方面:在03月10日这天,注册玩家数达到峰值114035人,3月13日注册玩家达到次高峰63141人,正是因为这两天开展活动吸引了大量玩家,但随后总体新增玩家数量都维持在4-5万之间与活动前差别不大,且有轻微下降趋势,可见这两次的活动并没有带来实质性的帮助,在这方面可能需要推出持续性刺激注册的活动或加加大活动力度。
  • 新增付费玩家:开展3月16日刺激充值活动,当天新增付费玩家数达到最高1703人,之前每日新增付费玩家数在900-1250之间,活动过后区间在1220-1412之间有所好转,但数据记录的最后一天新增付费玩家仅有1091人,推测可能是当天人数没有统计完成,所以暂不考虑,现在姑且认为刺激充值的活动有效。

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

直方图结果:

  • 付费玩家的平均时长远远超过全体玩家的平均时长达到了135.87分钟

箱线图结果:

  • 全体玩家上四分位数为5,下四分位数为0.5,平均值为1.67,最大值却达到了1065,全体玩家的流失都比较高,超过75%的玩家在线时间仅5分钟以内
  • 付费玩家上四分位数为191,下四分位数为30,平均值为84.5,最大值为1081,付费玩家的平均在线时长相对来对比较高,超过75%的玩家在线时长达到了30分钟

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()
  • 大部分玩家的游戏时长很短,仅仅有几分钟,可见玩家流失的情况时比较严重的
  • 付费玩家虽然游戏时长较高,但也大部分集中在100分钟以内

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()
  • 游戏在线时长与充值金额分布图中,整体玩家的充值金额均在1000元以内,最高充值金额接近1.5w,但他们的游戏时长分布在0-1000分钟占比都比较均匀,由此可见,游戏在线时长与充值金额相关性并不高

4. 玩家付费情况分析

关键指标

  • AU:活跃用户,这里将游戏时长达15分钟的定为活跃用户
  • PU:付费用户
  • APA:活跃付费用户
  • ARPU:平均每个活跃用户的收入,总收入/AU
  • ARPPU:平均每个活跃付费用户收入,总收入/APA
  • PUR:付费比率,APA / AU

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()
  • 总玩家数有82万,但活跃用户仅有10w,占比12%左右
  • 付费玩家仅有不到2w人,活跃用户付费率为16.9%,活跃付费玩家较少,说明游戏的收入表现较差
  • 通过ARPU和ARPPU对比,活跃玩家人均收入仅有5元,但活跃付费玩家人均收入有32元,说明活跃付费玩家的付费能力较强,针对这一点,我们可以做一些付费功能调整和优化,可以针对大R玩家进行针对性服务。

注意:大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()
  • 从上图可以看出,APA玩家的平均PVE和PVP次数都要高于AU玩家两倍左右,显然APA玩家更愿意花费更多的时间在这个游戏上。
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()
  • 在PVE活动中,APA玩家主动发起进攻的概率和胜利的概率与AU玩家基本持平,其中主动发起PVE的概率非常高,可见游戏玩家还是比较熟悉游戏规则,基本上能主动刷副本打怪获取资源或者等级的提升。另外游戏的PVE难度也不高,玩家的PVE胜率高达90%,可见游戏体验较为友好

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

结论

1.新增用户分析
  • 新增玩家有828934人,其中付费玩家有19549人,付费人数占注册总人数的2.36%。
  • 每日新增玩家在3月10日有一次大高锋增长,在3月13日有一次小高峰增长。推断可能是举办了游戏活动,但是活动一过,后续新用户注册量并没有显著提升,可见这两次活动并没有给游戏的人气带来实质性的帮助。
  • 在这两次活动举办期间,每日新增付费用户并没有提升,反而趋于下降,可见这两次活动主要是为了提高游戏热度。
  • 建议加大活动力度,并保持一定的时间维度,给玩家充分了解游戏的时间,才能持续提高游戏热度。
2.玩家活跃度分析
  • 全部玩家平均在线时长11.74分钟,付费玩家平均在线时长135.87分钟,付费玩家的平均在线时长要远远大于全体玩家的平均值,活跃度比他们大得多。
  • 75%的玩家平均在线时长不超过1分钟,可见玩家流失的情况还是比较严重的。
  • 付费用户中,75%以上的的用户在线时长都超过了30分钟,说明付费用户更加愿意投入时间到该款游戏中
3.玩家付费情况分析
  • 付费率PUR比较低,只有2.70%。其实只要简单地开展一个首充活动,比如充1元可获得价值60元的大礼包,就能很好地提高游戏的付费率了。付费率高,一样可以得到渠道青睐,获得更多推荐展示机会(行业俗称为“吸量”),间接提高游戏的热度。
  • 目前较好的手游每日ARPU超过5元;一般的手游ARPU在3~5元之间;ARPU低于3元则说明表现较差。该手游平均每用户收入ARPU很低,说明游戏的收入表现较差,但是平均每付费用户收入ARPPU很高,说明大R的付费能力强,针对这一点,我们可以做一些付费功能的调整和优化,甚至专属大R的客服,让付费用户玩的更开心。
4.付费玩家习惯分析
  • APA玩家的平均PVE和PVP次数都要高于AU玩家两倍左右,显然APA玩家更愿意花费更多的时间在这个游戏上
  • 在PVP活动中,APA玩家主动发起进攻的概率和胜利的概率要明显高于AU玩家,在享受游戏对战乐趣的过程中,往往更能够收获胜利。
  • 在PVE活动中,APA玩家主动发起进攻的概率和胜利的概率与AU玩家基本持平,其中主动发起PVE的概率非常高,可见游戏玩家还是比较熟悉游戏规则,基本上能主动刷副本打怪获取资源或者等级的提升。
  • 游戏的PVE难度也不高,玩家的PVE胜率高达90%,可见游戏体验较为友好
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342