python数据分析实战---用户行为分析

相关精彩专题链接: 数据成就更好的你

本案例数据下载: https://pan.baidu.com/s/1HZ8mygqr-cJSVUyIQuX1bA 提取码: kkvv

整体概述
本案例的数据为小程序运营数据,以行业常见指标对用户行为进行分析,包括UV、PV、新增用户分析、漏斗流失分析、留存分析、用户价值分析、复购分析等内容。其分析框架如下图:


image.png

一、数据提取

import pandas as pd
import numpy as np
from sqlalchemy import create_engine
import datetime
import matplotlib.pyplot as plt
%matplotlib inline
plt.rcParams['font.sans-serif'] = ['SimHei'] 
plt.rcParams['axes.unicode_minus'] = False  

#数据存储在mysql数据库中
conn=create_engine("mysql+pymysql://用户名:密码@127.0.0.1:3306/数据库名称?charset=utf8")
data=pd.read_sql("behavior",conn)

本数据集约76万条数据


image.png

二、数据处理

#1.观察数据,查看数据内容包含什么
data.head()

#2.数据去重处理
data.drop_duplicates(inplace=True)

#3.时间戳time数据处理。转化为访问网站的具体时间、月份、日期、每天几点访问
data["time1"]=data["time"].apply(lambda x:datetime.datetime.fromtimestamp(x))
data["month"]=data["time"].apply(lambda x:int(datetime.datetime.fromtimestamp(x).strftime("%Y%m")))
data["date"]=data["time"].apply(lambda x:datetime.datetime.fromtimestamp(x).strftime("%Y%m%d"))
data["hour"]=data["time1"].apply(lambda x:x.hour)

#4.销售金额计算
data["money"]=data["price"]*data["amount"]

#5.缺失值处理:观察有没有缺失值,有缺失值则对缺失值处理。本数据集没有缺失值
data.isnull().sum()

#6.观察数据有没有异常值。总共757565条记录,和时间相关的数据都正常,其他字段也无异常值
data.describe()
test2.jpg

三、用户行为分析:pv/uv
1、pv/uv 按天分析,观察其访问走势

all_puv=pd.pivot_table(data,index=["date"],values="user_id",aggfunc="count")
uv=data[["user_id","date"]].drop_duplicates()["date"].value_counts()
all_puv=all_puv.join(uv)
all_puv.columns=["pv","uv"]
all_puv["avg_pv"]=all_puv["pv"]/all_puv["uv"]
all_puv
image.png
image.png

2、pv/uv 按天分析,观察每个行为操作的点击量

pv=pd.pivot_table(data,index=["date"],columns=["behavior"],values="user_id",aggfunc="count")
pv["all"]=pv.sum(axis=1)
image.png
plt.figure(figsize=(12,5))
plt.plot(pv.index,pv["all"])
plt.plot(pv.index,pv["pv"],color="r")
plt.plot(pv.index,pv["cart"],color="b")
plt.plot(pv.index,pv["buy"],color="c")
plt.plot(pv.index,pv["fav"],color="y")
plt.xlabel("日期",fontsize=12)
plt.ylabel("pv",fontsize=12)
plt.title("用户行为pv分析",fontsize=16)
plt.legend( ["all","pv","cart","buy","fav"],loc = 'upper left',fontsize=12)
plt.show()
image.png

3.观察用户每天的访问高峰区。本数据集中,访问高峰期为晚上19点至23点

hour_pv=data["hour"].value_counts().reset_index().rename(columns={'index':'hour', 'hour':'pv'})

plt.figure(figsize=(12,3))
plt.bar(hour_pv["hour"],hour_pv["pv"])
plt.xlabel("小时",fontsize=12)
plt.ylabel("访问量pv",fontsize=12)
plt.title("用户按小时统计的访问量",fontsize=16)
plt.show()
image.png

四、获客分析
获客分析:观察每日新增用户情况。新用户的定义:第一次访问网站

new_visitor=data[["user_id","date"]].groupby("user_id").min()["date"].value_counts().reset_index()
new_visitor.columns=["date","new_visitor"]

plt.figure(figsize=(8,3))
x,y=new_visitor["date"],new_visitor["new_visitor"]
plt.bar(x, y, width=0.6)
for a, b in zip(x, y):
    plt.text(a, b + 0.05, '%.0f' % b, ha='center', va='bottom', fontsize=10)
plt.xlabel("日期",fontsize=12)
plt.ylabel("新用户数",fontsize=12)
plt.title("每日新增用户数",fontsize=16)
plt.show()
image.png

五、用户留存分析
留存定义为 1月1日,新增用户200人;
次日留存:第2天,1月2日,这200人里面有100人活跃,则次日留存率为:100 / 200 = 50%
2日留存:第3天,1月3日,这200名新增用户里面有80人活跃, 第3日新增留存率为:80/200 = 40%; 以此类推

#建立n日留存率计算函数,data传入的为用户id和登录日期, start_date为起始时间(格式为:%Y%m%d),n为n日留存,不传入start_date和n时,则计算所有留存
def cal_retention(data,start_date="20100101",n=0):
   if n>0:
       new_user=data[["user_id","date"]].groupby("user_id").min().reset_index()
       date2=datetime.datetime.strptime(start_date,"%Y%m%d")+datetime.timedelta(n)
       end_date=datetime.datetime.strftime(date2,"%Y%m%d")
       
       start_user=set(new_user[new_user.date==start_date].user_id)
       end_user=set(data[data.date==end_date].user_id)
       user=start_user&end_user
       
       return [start_date,end_date,len(start_user),len(user),round(len(user)/len(start_user),4)]
   
   else:
       new_user=data[["user_id","date"]].groupby("user_id").min().reset_index()
       date_sourse=new_user.date.unique()
       date_sourse.sort()
       
       result1=[]
       flag=0

       for start_date in date_sourse:
           start_user=set(new_user[new_user.date==start_date].user_id)
           for end_date in date_sourse[flag:]:
               end_user=set(data[data.date==end_date].user_id)
               user=start_user&end_user
               result1.append([start_date,end_date,len(start_user),len(user),round(len(user)/len(start_user),4)])
           flag=flag+1        
       return pd.DataFrame(result1,columns=["开始日期","留存日期","新用户数","留存人数","留存率"])


#调用cal_retention函数计算留存。
#例:计算11约28日的3日留存,其返回结果为:['20191128', '20191201', 7610, 5980, 0.7858],此数据的含义为:28号的新用户数为7610,第3日的留存用户为5980,留存率为78.58%
cal_retention(data[["user_id","date"]],"20191128",3)

#调用cal_retention函数计算留存,只传入数据集
retention=cal_retention(data[["user_id","date"]])

#留存人数展示
pd.pivot_table(retention,index=["开始日期"],columns=["留存日期"],values="留存人数",aggfunc="sum",fill_value=0)

#留存率展示
pd.pivot_table(retention,index=["开始日期"],columns=["留存日期"],values="留存率",aggfunc="sum",fill_value=0)
image.png
image.png

六、复购分析
指在单位时间段内,重复购买率=再次购买人数/总购买人数。
例如在一个月内,有100个客户成交,其中有20个是回头客,则重复购买率为20%。
此处的回头客定义为:按天去重,即一个客户一天产生多笔交易付款,则算一次购买,除非在统计周期内另外一天也有购买的客户才算是回头客。

data_buy=data[data.behavior=="buy"][["user_id","date"]].drop_duplicates()["user_id"].value_counts().reset_index()
data_buy.columns=["user_id","num"]  #user_id表示用户id,num表示购买次数

#复购率计算
rebuy_rate=round(len(data_buy[data_buy.num>=2])/len(data_buy),4)
print("复购率为:",round(rebuy_rate*100,2),"%")     #输出结果为:42.06 %

#购买的总人数
buy_user=len(data_buy)

#购买次数的人数分布
buy_freq=data_buy.num.value_counts().reset_index()
buy_freq.columns=[["购买次数","人数"]]
buy_freq["人数占比"]=round(buy_freq["人数"]/buy_user,4)

从以下数据可以看出,一共有6110个用户有购买行为,购买1次的人数最多,为3540,占了57.94%。本数据集的复购率为42.06 %,商家需从商品质量、价格、促销活动、物流等多方面寻找问题点,需求高复购率的突破


image.png

七、RFM模型分析
RFM模型分析前提条件:
a. 最近有过交易行为的客户,再次发生交易的可能性高高于最近没有交易行为的客户;
b.交易频率较高的客户比交易频率较低的客户,更有可能再次发生交易行为;
c.过去所有交易金额较多的客户,比交易金额较少的客户,更有消费积极性。

#取数规则:最近一次消费的时间取最大,消费频次根据计数统计,消费金额求平均值统计
RFM_date=data[data.behavior=="buy"][["user_id","date"]].groupby("user_id").max()
RFM_F=data[data.behavior=="buy"][["user_id","behavior"]].groupby("user_id").count()
RFM_M=data[data.behavior=="buy"][["user_id","money"]].groupby("user_id").mean()
RFM=RFM_date.join(RFM_F).join(RFM_M)

#用户价值分层(RFM模型):模型计算的日期为 2019-12-05
end_date=datetime.datetime.strptime("20191205","%Y%m%d")  
#时间间隔天数计算
RFM["days"]=RFM["date"].apply(lambda x:(end_date-datetime.datetime.strptime(x,"%Y%m%d")).days)
RFM=RFM[["days","behavior","money"]]
RFM.columns=["间隔天数","消费频次","消费金额"]
image.png

模型打分,这里采用5分制,规则如下:


image.png

根据打分规则对数据进行处理

RFM["R_S"]=RFM["间隔天数"].apply(recency)
RFM["F_S"]=RFM["消费频次"].apply(frequency)
RFM["M_S"]=RFM["消费金额"].apply(monetary)
RFM["RFM"]=RFM.apply(lambda x: int(x.R_S*100+x.F_S*10+x.M_S),axis=1)
RFM.head()

每一个RFM代码都对应着一小组客户,开展市场营销活动的时候可以从中挑选出若干组进行。例如 :RFM代码为443的用户,其消费时间间隔比较短,消费频次和购买力都很高,可做为重点客户重点维护。计算结果如下:


image.png

八、漏斗分析---转化路径
转化路径定义:pv点击 ---cart放入购物车 ---buy购买

#导入绘制漏斗图的工具包
from pyecharts.charts import Funnel
from pyecharts import options as opts

#转化分析,转化路径为:pv点击 ---cart放入购物车 ---buy购买
data_behavior=data[data.behavior!="fav"]["behavior"].value_counts().reset_index().rename(columns={"index":"环节","behavior":"人数"})

#单一环节的转化率
temp1 = np.array(data_behavior['人数'][1:])
temp2 = np.array(data_behavior['人数'][0:-1])
single_convs = temp1 / temp2
single_convs = list(single_convs)
single_convs.insert(0,1)
data_behavior['单一环节转化率'] = single_convs

#总体转化率
flag=data_behavior['人数'][0]
data_behavior['总体转化率'] = data_behavior['人数']/flag

#总体转化漏斗
attrs=[a+":  "+str(round(b,2))+"%" for a,b in zip(data_behavior['环节'],data_behavior['总体转化率']* 100)]
attr_value=[round(a,2) for a in data_behavior['总体转化率']* 100]

funnel = Funnel()
funnel.add("商品", [list(z) for z in zip(attrs, attr_value)],label_opts=opts.LabelOpts(position="inside"))
funnel.set_global_opts(title_opts=opts.TitleOpts(title="总体转化漏斗分析"))
funnel.render_notebook()
image.png

九、商品销售分析
1.商品top分析----销售次数最多的商品,取前10

#商品top分析----销售次数最多的商品,取前10
buy_top=data[data.behavior=="buy"]["goods_id"].value_counts().head(10)

from pyecharts.charts import Bar
from pyecharts import options as opts

bar = Bar()
bar.add_xaxis(buy_top.index.tolist())
bar.add_yaxis("销售排名前10",buy_top.values.tolist(),color="green")
bar.set_global_opts(title_opts=opts.TitleOpts(title="销售排名前10"))
#bar.render()
bar.render_notebook()
image.png

2.商品top分析----浏览次数最多的商品,取前10

#商品top分析----浏览次数最多的商品,取前10
pv_top=data[data.behavior=="pv"]["goods_id"].value_counts().head(10)

from pyecharts.charts import Bar
from pyecharts import options as opts

bar = Bar()
bar.add_xaxis(pv_top.index.tolist())
bar.add_yaxis("浏览排名前10",pv_top.values.tolist(),color="green")
bar.set_global_opts(title_opts=opts.TitleOpts(title="浏览排名前10"))
#bar.render()
bar.render_notebook()
image.png

3.商品top分析----收藏次数最多的商品,取前10

#商品top分析----收藏次数最多的商品,取前10
fav_top=data[data.behavior=="fav"]["goods_id"].value_counts().head(10)

from pyecharts.charts import Bar
from pyecharts import options as opts

bar = Bar()
bar.add_xaxis(buy_top.index.tolist())
bar.add_yaxis("销售排名前10",buy_top.values.tolist(),color="green")
bar.set_global_opts(title_opts=opts.TitleOpts(title="销售排名前10"))
#bar.render()
bar.render_notebook()
image.png

4.城市购买力排名

#城市购买力排名
city_top=data[data.behavior=="buy"][["addr","money"]].groupby("addr").sum().sort_values("money",ascending=False)

from pyecharts.charts import Bar
from pyecharts import options as opts

bar = Bar()
bar.add_xaxis(city_top.index.tolist())
bar.add_yaxis("城市购买力",[round(a,2) for a in city_top.money])
#bar.render()
bar.render_notebook()
image.png

5.不同性别的消费贡献情况

#不同性别的消费贡献情况 sex中:0代表女性,1代表男性
sex_top=data[data.behavior=="buy"][["sex","money"]].groupby("sex").sum()

from pyecharts.charts import Pie
from pyecharts import options as opts

base_pie = Pie()
base_pie.add("", [list(z) for z in zip(['女','男'], [round(a,2) for a in city_top.money])])
base_pie.set_global_opts(title_opts=opts.TitleOpts(title="不同性别的购买力"))
base_pie.set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}  ({d}%)"))  #自定义显示格式(b:name, c:value, d:百分比)
base_pie.render_notebook()
image.png

6.商品类目销售情况分析

cat_top=data[data.behavior=="buy"]["cat"].value_counts().head(10)

from pyecharts.charts import Bar
from pyecharts import options as opts

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

推荐阅读更多精彩内容

  • ----广告指标---- 不同时期产品的宣传必要要选择合适的投放媒体和渠道,这就需要我们了解基本的广告相关数据指标...
    冇话king啲佛跎阅读 2,074评论 1 7
  • 1.自我介绍 2.你对数据分析师工作的认识?认为数据分析师工作职责分为哪几块 ? 是什么:在数据中挖掘对业务有用的...
    微斯人_吾谁与归阅读 2,212评论 0 9
  • 法国为欧洲国土面积第三大、西欧面积最大的国家,东与比利时、卢森堡、德国、瑞士、意大利接壤,南与西班牙、安道尔、摩纳...
    泡沫金刚阅读 1,325评论 0 4
  • 湖畔的诗人与泥泞 为了赞美星辰而污秽缠身 流动的星辰 银河轻声低语 告诉了诗人一些瑰丽的秘密 诗人热泪盈眶 在星辰...
    伍丁零阅读 177评论 2 1
  • 我走了 你别哭, 别难过。 我不是那个陪你看星星的人 你看啊,我会自渡。 别担心,别打扰。 我快到对岸了
    沙鱼_阅读 181评论 0 0