玩家的等级成长曲线

在一款游戏中,数值策划会在游戏的设计阶段,规划玩家的等级成长的曲线,
包括每个等级需要的资源数,不同付费级别的玩家在每个等级的驻留时间等。
在游戏上线后,就需要去获取玩家的实际的成长曲线,和策划的设计曲线做对比,看看有没有偏差之类的。
本篇主要讲怎么去分析玩家的等级成长曲线,并绘制图形。
首先确定做这个分析一共需要的数据:
时间戳,玩家的注册时间,玩家id,各个时间戳下的游戏内等级和玩家的付费等级。
随便在日志中找个经常被触发的命令,带有时间戳和当前等级就行。
比如下面这种:


然后需要找到玩家的注册时间,得到每一行数据对于该玩家的注册时间的天数差,
再去个重就可以得到玩家的游戏天数和等级的数据了。

查询天数差的sql如下

SELECT
  item.uid,
  item.level,
--当前时间减去注册时间得到天数差--
  datetime_diff(datetime(item.ts),  datetime(reg.ts), DAY) AS day
FROM
  `cmd表` AS item
LEFT JOIN
  `regist表` AS reg
ON
  reg.uid = item.uid
WHERE
  DATE(item.ts, '+08') BETWEEN "2020-10-12"  AND "2020-11-26"
GROUP BY
  1,  2,  3
ORDER BY
  1,  2

用pandas找到玩家每天的最大等级

#按照uid和day分组,取level的最大值的索引,再根据索引筛选数据,同时也是去除重复的数据
level = level.loc[level.groupby(by=['day','uid'])['level'].idxmax()]

使用pivot_table转换下行列

le = level.pivot_table(index='uid', columns='day', values='level')
image.png

这样就得到了玩家等级随天数的变化情况。
但是这样还有两个问题, 第一个是上图第一个框中的,在两天数据中有缺失值。
这表示玩家在这天没有触发过这条命令,如果你选的是登陆必触发的命令则说明玩家在当天没有登陆。
这种可以直接按照上一次的等级填充。
然后是第二种情况,玩家直接弃坑了,这种就不需要填充数据。
因为弃坑后他的等级是不会变的,如果纳入统计会很大的拉低整体的数据值。
所以综合下就是在玩家弃坑前的缺失值要填充,弃坑后就不填充。
那么直接从后往前遍历,找到第一个不为空的数据,就是玩家的弃坑时间,然后填充前面的值就好了。

def fill_level(row):
    for i in range(45,-1,-1):
         if not np.isnan(row.iloc[i]):
            return row[:i+1].fillna(method='ffill')
le = le.apply(fill_level, axis=1)

现在拿到了基本的玩家等级随天数变化的数据,然后和充值表连表,找到每个玩家的充值等级。

SELECT
uid, sum(value ) as total_buy
FROM
  `充值表` 
where server = '28'
group by 1

拿到玩家的充值数据后,按不同金额分段,比如按照100内为小R,100-1000为中R,1000以上为大R

buy['r'] = pd.cut(buy['total_buy'], [0, 100,1000,np.inf],
                  right=False, labels=['R', 'SR', 'SSR'])

看下各个等级有多少人:

buy['r'].value_counts()

R      184
SR      42
SSR      9

然后把我们的等级变化表和充值表连起来

leb = pd.merge(le, buy[['uid','r']], how='left', on='uid')

连表后充值玩家的等级已经和uid对应起来的,但是未充值玩家的这一列仍是空值,所以需要填充一下。
由于上面我们分等级的时候用了pd.cut,这一列的类型变为了category,直接使用fillna是会报错的。
因为category只允许插入分类中已有的值。
具体来说,在上面的labels中有['R', 'SR', 'SSR']这三个类型,那么fillna的值只能填这三个类型。
所以需要先插入一个未充值玩家的类型,在使用fillna填充。

# 在分类中插入N类型,再使用fillna做填充
leb['r'].cat.add_categories(['N'], inplace=True)
leb['r'].fillna('N', inplace=True)
leb['r'] = leb['r'].astype('str')

leb['r'].value_counts()

N      2045
R       138
SR       31
SSR       8

然后我们把每一个等级的数据提取出来,准备绘图

leN = leb[leb['r']=='N'].copy()
leR = leb[leb['r']=='R'].copy()
leSR = leb[leb['r']=='SR'].copy()
leSSR = leb[leb['r']=='SSR'].copy()

这里使用箱线图,因为箱线图可以表示一个数据的分布,再加上平均值,可以较好的展示真实的数据。

plt.figure(figsize=(24, 9), dpi=80)
t = le.drop(['uid', 'r'], axis=1)
lm = t.mean()
# 这里索引不加1的话,折线图的X轴会和箱线图的X轴是对不上,具体我也不知道为啥。。。
lm.index += 1
lm.plot(c='g', label=' N average line')
t.boxplot(color='r')
plt.legend()

现在拿到了玩家的成长数据了,接下来把策划设计的线加上就可以了。

plt.figure(figsize=(24, 9), dpi=80)
t = le.drop(['uid', 'r'], axis=1)
lm = t.mean()
# 这里索引不加1的话,折线图的X轴会和箱线图的X轴是对不上,具体我也不知道为啥。。。
lm.index += 1
lm.plot(c='g', label=' N average line')
# 根据策划给出的等级成长规划得到的数据
N_up_line.plot(c='b', label='N design line')
t.boxplot(color='r')
# 设置标题
plt.title('all user')
# 画出线段说明,下图左上角的那个
plt.legend()
plt.show()


剩下的就是画出不同充值等级的玩家的图表了,代码都是一样的,
改下t = le.drop(['uid', 'r'], axis=1)就可以了。
可以从图中看出,前期玩家至少有一半是没跟上策划的规划线的,那么就可以从其他方便查找一下没跟上的原因,然后采取一些手段优化玩家的成长体验。
箱线图的具体说明如上下限、异常值怎么算的,请自行百度。
-- end --

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

推荐阅读更多精彩内容