CD销售分析

项目介绍

该数据来源于某CD网站的销售记录。通过对该数据的分析,了解整体的消费趋势以及用户个体的消费行为,在RFM模型下用户的分层,探究用户生命周期。
数据链接:https://pan.baidu.com/s/1OfQzPvktlykDczdlk3uUsQ
提取码:pcne

本文分析的主要框架

1.进行用户消费趋势的分析(按月):探究每月消费的人数、金额、次数等
2.用户个体消费分析:分析个体用户的消费金额、购买量的描述统计、散点图,探究其在总体消费金额中的占比
3.用户消费行为:用RFM模型进行用户分层并分析用户的购买周期、生命周期等
4.复购率及回购率分析
5.结论及建议

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
columns = ['user_id','order_dt','order_products','order_amount']
df = pd.read_table(r'F:\data\CDanalysis\CDNOW_master.txt',names=columns, sep='\s+')
df.head()
image.png
df.info()
image.png

原始数据中共有4个字段,每个字段共69659行,数据没有缺失,字段解释如下:
user_id: 用户ID
order_dt:订单日期
order_products:商品数量
order_amount:订单金额

df['order_dt']=pd.to_datetime(df.order_dt,format='%Y%m%d')#将订单时间的格式修改为年-月-日的形式
df['month']=df.order_dt.values.astype('datetime64[M]')#在原始数据的结构上增加‘月份’列
df.head()
image.png

1.进行用户消费趋势的分析(按月)

a.每月的消费总金额
grouped_month=df.groupby(by='month')
grouped_month.order_amount.sum().plot()
image.png
b.每月的消费次数
grouped_month.user_id.count().plot()
image.png
c.每月的产品购买量
grouped_month.order_products.sum().plot()
image.png
d.每月的消费人数
grouped_month.user_id.apply(lambda x:len(x.drop_duplicates())).plot()
#grouped_month.user_id.apply(lambda x: x.drop_duplicates().count()).plot() #另一种方法
image.png

从以上四幅折线图可以看出,在前三个月消费总金额、消费次数、产品购买量、消费人数都呈上升趋势,而在四月份骤然下降。

2.用户个体消费分析

a.用户的消费金额、购买量的描述统计
grouped_user=df.groupby('user_id')
grouped_user.sum().describe()
image.png

以用户ID分组的描述统计来看,平均每位用户购买量约为7,购买金额约为106;而用户最多的购买量为1033,购买金额为13990.93;至少有一半的用户购买量在3及3以下,购买金额在43.395及以下。

b.用户的消费金额、购买量的散点图
grouped_user.sum().query('order_amount < 4000').plot.scatter(x='order_amount', y='order_products')
#grouped_user.sum().plot.scatter(x='order_amount', y='order_products')
image.png

从散点图来看,用户的消费金额主要集中在0-1500元,产品购买量集中在0-100。

c.用户累计消费金额占比
user_cumsum=grouped_user.sum().sort_values('order_amount').apply(lambda x: x.cumsum()/x.sum())
user_cumsum.reset_index().order_amount.plot()
image.png

3.用户消费行为

a.用户第一次消费(首购)
grouped_user.order_dt.min().value_counts().plot()
image.png
用户最后一次消费
grouped_user.order_dt.max().value_counts().plot()
image.png

用户最后一次消费,可见大部分的用户在前3个月只消费一次就不消费了。

多少用户仅消费了一次
user_life=grouped_user['order_dt'].agg(['min','max'])
(user_life['min']==user_life['max']).value_counts()
image.png

总共有12054个用户只消费了一次。

b.用户分层

RFM模型

rfm=df.pivot_table(index='user_id',
                   values=['order_dt','order_products','order_amount'],
                   aggfunc={'order_dt':'max','order_products':'count','order_amount':'sum'}
                  )
rfm['R']=(rfm.order_dt.max()-rfm.order_dt)/np.timedelta64(1,'D')
rfm.rename(columns={'order_amount':'M','order_products':'F'},inplace=True)
a=rfm[['R','F','M']].apply(lambda x: x-x.mean())
RFM=a.applymap(lambda x: '1' if x>0 else '0')
def RFM_func(x):
    label=x.R+x.F+x.M
    b={
    '111':'重要价值客户',
    '011':'重要保持客户',
    '101':'重要发展客户',
    '001':'重要挽留客户',
    '110':'一般价值客户',
    '010':'一般保持客户',
    '100':'一般挽留客户',
    '000':'一般发展客户'
}
    result=b[label]
    return result
RFM['label']=RFM.apply(RFM_func,axis=1)
RFM.head()
image.png

RFM模型,其中R表示最近一次消费时间,F表示消费频次,M表示消费金额。用RFM模型进行用户群体划分。

RFM.groupby('label')['F'].count().plot.pie(autopct='%.2f%%')

image.png

重要价值客户占比1.9%,大部分客户都是购买金额比较小的一般客户。
用户分层--新、活跃、回流、流失/不活跃

pivoted_counts=df.pivot_table(index='user_id',
                              columns='month',
                              values='order_dt',
                              aggfunc='count').fillna(0)
df_purchase=pivoted_counts.applymap(lambda x: 1 if x>0 else 0)
def active_status(data):
    status=[]
    for i in range(18):
        #若本月没有消费
        if data[i]==0:                       
            if len(status)>0:
                if status[i-1]=='未注册':
                    status.append('未注册')
                else:
                    status.append('不活跃')
            else:
                status.append('未注册')
        #若本月消费
        else:
            if len(status)>0:
                if status[i-1]=='未注册':
                    status.append('新用户')
                elif status[i-1]=='不活跃':
                    status.append('回流')
                else:
                    status.append('活跃')
            else:
                status.append('新用户')
    return status
    #data.iloc[0:]=status
    #return data
    
purchase_status=df_purchase.apply(active_status,axis=1)
purchase_status.head()
image.png

将每个用户在不同月份的状态以‘新用户’、‘活跃’、‘回流’、‘不活跃’来进行用户分层。

purchase_status_count=purchase_status.replace('未注册',np.NaN).apply(lambda x:x.value_counts())
purchase_status_count
image.png

新用户在前三个月不断增加,从四月份开始就没有新用户注册,活跃用户后期稳定在500人左右。

purchase_status_count.fillna(0).T.apply(lambda x: x/x.sum(),axis=1).head()
image.png
c.用户购买周期

统计描述

#order_diff=grouped_user.apply(lambda x: x.order_dt-x.order_dt.shift())
order_diff=grouped_user['order_dt'].apply(lambda x: x-x.shift())
order_diff.describe()

image.png

至少有75%用户购买时间间隔在89天及以下,平均用户购买周期为68天。
分布

(order_diff/np.timedelta64(1,'D')).hist(bins=20)
image.png
d.用户生命周期

统计描述

#user_life=grouped_user['order_dt'].agg(['min','max'])  (引用前面的user_life)
(user_life['max']-user_life['min']).describe()

image.png

平均用户生命周期为134天,最长的为544天,但是至少有一半的用户生命周期为0。
分布

((user_life['max']-user_life['min'])/np.timedelta64(1,'D')).hist(bins=20)
image.png
#受只消费一次的用户影响严重,因此去掉只消费一次的用户进行绘画分布图
user_life['a']=(user_life['max']-user_life['min'])/np.timedelta64(1,'D')
#user_life.head(10)
user_life.loc[user_life['a']> 0]['a'].hist(bins=20)
image.png

4.回购率和复购率分析

a.复购率
pivoted_counts.head(5)
image.png
purchase_r=pivoted_counts.applymap(lambda x: 1 if x>1 else np.NaN if x==0 else 0)
(purchase_r.sum()/purchase_r.count()).plot(figsize=(10,4))
image.png

复购率在四月份之前一直呈现上升趋势,四月份以后有些微波动,但是基本稳定在20%左右

b.回购率
df_purchase.head()
image.png
def purchase_back(data):
    status=[]
    for i in range(17):
        if data[i]==1:
            if data[i+1]==1:
                status.append(1)
            else:
                status.append(0)
        else:
            status.append(np.NaN)
    status.append(np.NaN)#将最后一个月份填充好
    return status
purchase_b=df_purchase.apply(purchase_back,axis=1)
(purchase_b.sum()/purchase_b.count()).plot(figsize=(10,4))
image.png

回购率在五月份之前呈上升趋势,五月份以后在25%-40%之间波动

5.结论及建议

1、用户消费趋势的分析(按月)

  • 结论汇总:在前三个月消费总金额、消费次数、产品购买量、消费人数都呈上升趋势,而在四月份骤然下降,四月份之后稳定在低水平状态。
  • 后续改进:在四月份之后举办一些优惠活动吸引新用户、促活流失用户等来提高消费金额、消费人数等。

2、用户个体消费分析

  • 结论汇总:
    1)描述统计来看,平均每位用户购买量约为7,购买金额约为106;而用户最多的购买量为1033,购买金额为13990.93;至少有一半的用户购买量在3及3以下,购买金额在43.395及以下。
    2)用户的消费金额主要集中在0-1500元,产品购买量集中在0-100。
  • 后续改进:
    1)可以分析最受用户欢迎的商品和其他一些相关的商品做一些捆绑销售,带动其他商品的销量,从而提高产品购买量;
    2)对购买金额较大的用户做好售后,分析这些用户特点,在用户运营方面考虑侧重于相关用户。

3.用户消费行为分析

  • 结论汇总
    1)大部分的用户在前3个月只消费一次就不消费了,且总共有12054个用户只消费了一次。
    2)用RFM模型进行用户群体划分,重要价值客户占比1.9%,重要保持客户占19.59%,大部分客户都是购买金额比较小的一般客户。
    3)用户在不同月份的状态以‘新用户’、‘活跃’、‘回流’、‘不活跃’来进行用户分层,新用户在前三个月不断增加,从四月份开始就没有新用户注册,活跃用户后期稳定在500人左右。
  • 后续改进:
    1)用户只消费了一次可能是被最开始的活动所吸引,建议多做一些促销活动,可以以节日为主题带动用户消费。
    2)对于购买金额较大的用户要做好客户关怀,不断提高他们经常购买的产品的质量;而对于购买金额较小但却在用户量中占比最大的用户可以用捆绑销售来尽量提高他们的购买总额。
    3)从第四个月后没有新用户加入是一个严重的问题,可以不断开拓营销渠道、举办活动以及用老带新的方式来开拓新用户;同时促活流失用户。

4.回购率和复购率分析

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

推荐阅读更多精彩内容

  • 数据是来自于CDNow网站的用户购买明细。一共有用户ID,购买日期,购买数量,购买金额四个字段。 我们通过案例数据...
    杨昊_6c65阅读 2,746评论 1 10
  • 目录 前言一. 数据预处理1.1 数据导入1.2 数据清洗二. 月用户消费趋势分析2.1 每月消费总金额2.2 每...
    米兔妮妮阅读 1,661评论 0 10
  • 首先当然要把该import的都全部Import进来。 为了待会儿画图正常显示中文。因为我是MAC系统,所以代码跟W...
    曾立韬阅读 1,185评论 0 2
  • 前言:本文数据量来源于网上,是一份CD的消费数据,数据链接会放在文章最后,请需要者自取。本文分析的主要工具为:Py...
    黑哥666阅读 4,138评论 2 7
  • 拆解《金融的解释》 ...
    张宝英阅读 474评论 0 0