Python数据分析之对比

现状

某社交游戏公司有一款游戏本月的销售额相比上月有所下滑,需要我们分析下滑的原因,并提升销售额。这个游戏的销售额之前一直保持增长,而这个月却下降了。从市场环境和游戏本身的状态来看,不太可能由于游戏本身内容导致,于是我们需要找出哪些用户产生差异导致销售额下降。

近两个月销售额数据

发现问题

首先,我们需要知道本月和上月相比有哪些点不同。我们尝试进行下述假设。销售额减少的原因可能有以下两点:
1. 在营销宣传上存在问题
2. 每月开展的游戏活动存在问题

提出假设后我们需要检验假设是否正确,最简单的方式是询问相关部门。通过咨询是市场部和游戏开发部,得到以下信息:
1. 由于营销预算有限,本月相比上月并没有开展那么多宣传活动
2. 游戏活动主题和内容相比上月几乎没有变动

从上面信息可以发现销售额减少可能由于宣传活动减少,导致公司产品在用户纳新方面不足,现在我们需要通过数据确认新用户数量减少和销售额下降是否存在关系。

数据收集和处理

通过跟技术部沟通分析需求的数据支持,收集到如下数据:
1. DAU(Daily Active User,每天至少来访 1 次的用户数据)
2. DPU(Daily Payment User,每天至少消费 1 元的用户数据)
3. Install(记录每个用户首次玩这个游戏的时间的数据)

  • DAU
数据字段 数据类型 数据名称
log_date string 访问时间
app_name string 应用名称
user_id int 用户ID
  • DPU
数据字段 数据类型 数据名称
log_date string 消费日期
app_name string 应用名称
user_id int 用户ID
payment int 消费金额
  • Install
数据字段 数据类型 数据名称
install_date string 首次使用时间
app_name string 应用名称
user_id int 用户ID

读取数据文件
本例的数据都是以csv文件存储,使用Pandas库可以将csv文件读取成DataFrame数据,方便后续进行数据处理。具体代码如下:

# 导入相关库
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

%matplotlib inline

# 读取csv数据
dau = pd.read_csv('data/dau.csv')
dpu = pd.read_csv('data/dpu.csv')
install = pd.read_csv('data/install.csv')

注:%matplotlib inline是我因为使用jupyter notebook进行编辑,为了显示图表需要添加此行。

查看读取的数据
head方法可以显示数据头五行。

dau.head()
dau
dpu.head()
dpu
install.head()
install

数据合并
merge函数可以将两份数据进行合并,类似SQL里面的join,但功能要更加强大。首先将DAU和install的数据进行合并,合并的数据能计算当月新用户和已有用户。再将得到的数据与用户消费信息数据DPU合并,这样可以计算用户当月的消费金额情况。

# 合并DAU和install数据
dau_install = pd.merge(dau, install, on=['user_id', 'app_name'])

# 合并上述数据和DPU数据
dau_install_payment = pd.merge(dau_install, dpu, how='left', on=['log_date', 'app_name', 'user_id'])
dau_install.head()
dau_install
dau_install_payment.head()
dau_install_payment

查看最终合并后的数据发现消费金额payment显示NaN即该值为空,这是因为只有产品消费行为的用户才有消费金额,否则就没有数据,缺失的数据在合并后会显示NaN。

实际上有消费金额的数据和NaN混合在一起,这里只查看了前五行数据全显示为NaN,所以我们还无法确定消费金额数据是否与之前的数据正确合并。为了查看消费金额非空的数据,需要进行一下操作:

# 查看payment不为空数据
dau_install_payment[dau_install_payment['payment'].notnull()].head()

看到不为NaN数据有实际的值,即payment正确合并在一起。

数据处理
前面我们合并用户的消费数据,但未消费用户的消费金额为NaN值,因为payment需要参与到后续计算,NaN值则不是最好的标识,所以需要将这些值设置为零。

# 将未消费用户的消费金额设置为零
dau_install_payment['payment'] = dau_install_payment['payment'].fillna(0)
dau_install_payment

数据探索分析

按月统计
现在得到的分析数据日期都是年月日类型,如要要按月统计则需重新生成月份的列来表示。利用lambda函数从日期中提取第1到7个字符,使用日期log_date和首次使用日期install_date都需要进行处理。为了观察上月与本月的差别,数据将按照月份进行统计用户信息。

# 增加两列表示月份
dau_install_payment['log_month'] = dau_install_payment['log_date'].map(lambda x: x[0: 7])
dau_install_payment['install_month'] = dau_install_payment['install_date'].map(lambda x: x[0: 7])

# 按使用月份、用户ID和首次使用月份分组汇总消费金额合计
mau_payment = dau_install_payment.groupby(['log_month', 'user_id', 'install_month'])['payment'].sum().to_frame().reset_index()
mau_payment.head()
mau_payment

区分新用户和已有用户
如果用户的使用月份和首次使用月份一致,则该用户为新用户,否则为已有的用户,下面我们将对用户类型进行区分。

# 增加识别新用户和已有用户
mau_payment['user_type'] = np.where(mau_payment['log_month'] == mau_payment['install_month'], 'install', 'existing')
mau_payment.head()
mau_payment

为了确认新用户是否减少了,按月统计不同用户类型的消费额,对比发现7月相比6月新用户大幅减少。

# 按月份和用户类型分组求消费金额合计
mau_paymnet_summary = mau_payment.groupby(['log_month', 'user_type'])['payment'].sum().to_frame().reset_index()
Paste_Image.png

数据可视化

通过前面的汇总数据可以发现本月与上月之间的差异,但不是特别直观,所以我们用可视化图表来表示两者的差异情况。如下图,本月相比上月消费额减少,但已有用户的消费金额并没有明显变化,新用户消费金额减少明显。

# 按使用月份和用户类型分组汇总消费金额绘制叠加柱状图
mau_payment.groupby(['log_month', 'user_type'])['payment'].sum().unstack().plot(kind='bar', stacked=True, alpha=0.8, rot=True)
plt.ylabel('total_payment')
plt.legend()
plt.show()

两个月的消费额分布比较

从上面的初步分析结果可以验证我们之前的假设,即新用户数减少导致销售额下降。那么具体是哪个消费层级的消费额减少?

先抽取新用户的消费数据,将两个月份的数据分别绘制直方图并重叠对比。横坐标表示该月的消费金额总计,纵坐标表示相应的用户数。通过可视化图表可以看出消费额2000以下的用户减少了。在社交游戏中,用户可以用金钱来购买劳动。由于大部分用户消费得很少,所以你只需要花不多的钱就可以让自己的排名大幅上升。然而,如果你想占据排行榜的顶端,那么所要花费的金额马上就会上涨。这也是人们的竞争心理结构在数据分布上的表现。

# 对比不同月份消费金额分布
install_payment = mau_payment[(mau_payment['payment'] > 0) & (mau_payment['user_type'] == 'install')]
data1 = install_payment[install_payment['log_month'] == '2013-06']['payment']
data2 = install_payment[install_payment['log_month'] == '2013-07']['payment']

bins = np.arange(0, 13000, 1000)

data1.hist(bins=bins, alpha=0.7, label='2013-06')
data2.hist(bins=bins, alpha=0.8, label='2013-07')
plt.ylabel('payment')
plt.legend()
plt.show()

解决方案

基于前面的分析结果,我们可以采取以下解决方案来提高销售额。
1. 公司恢复之前营销宣传的活动水平,提高潜在用户对公司产品的认知度
2. 打包小额游戏促销包,提高小额消费新用户数量

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

推荐阅读更多精彩内容