数据库相连的消费者分析(二)

3.用户消费行为

  • 用户第一次消费(首购)
  • 用户最后一次消费
  • 新老客消费比
    • 多少用户仅消费一次?
    • 每月新客占比
  • 用户分层
    • RFM
    • 新、老、活跃、回流、流失
  • 用户购买周期(按订单)
    • 用户消费周期描述
    • 用户消费周期分布
  • 用户生命周期(按第一次&最后一次消费)
    • 用户生命周期描述
    • 用户生命周期分布
# 
grouped_user.min().reset_index().order_dt.value_counts().plot()

grouped_user.max().order_dt.value_counts().plot()

user_life=grouped_user.order_dt.agg(['min','max'])
user_idminmax
11997-01-011997-01-01
21997-01-121997-01-12
31997-01-021998-05-28
41997-01-011997-12-12
one=pd.DataFrame((user_life['min']==user_life['max']).value_counts())
a = pd.Series(one.iloc[1])
print("仅消费一次人数",a[0])
user_idorder_dtorder_productsorder_amountmonth
011997-01-01111.771997-01-01
121997-01-12112.001997-01-01
221997-01-12577.001997-01-01
331997-01-02220.761997-01-01
431997-03-30220.761997-03-01

每月新客占比

# 统计每个月每个用户最早最后消费时间
month_count=df.groupby(['month','user_id']).order_dt.agg(['min','max'])
monthuser_idminmax
1997-01-0111997-01-011997-01-01
21997-01-121997-01-12
31997-01-021997-01-02
41997-01-011997-01-18
51997-01-011997-01-14
# 判断只消费了一次的用户
month_counts=pd.DataFrame(month_count['min']==month_count['max'])
# 统计消费一次和多次用户的个数
month_new_oldd=month_counts.reset_index().groupby(['month',0]).count().reset_index()
# 修改列名
month_new_oldd.columns=['month','TF','user_id']
# 筛选出仅消费一次的客户
month_newnum=month_new_oldd.loc[month_new_oldd.TF==True]
monthTFuser_id
11997-01-01True7093
31997-02-01True8571
51997-03-01True8154
71997-04-01True2228
# 统计每个月总消费人数
month_count=df.groupby(['month','user_id']).count().reset_index().groupby('month').count()
month_usercount=month_count.reset_index().iloc[:,:2]
monthuser_id
01997-01-017846
11997-02-019633
21997-03-019524
31997-04-012822
41997-05-012214
# 连接单次消费人数表和总人数表
month_new_old=month_newnum.merge(right=month_usercount,on='month')
# 计算每月新客占比
month_new_old['newper']=month_new_old.user_id_x/month_new_old.user_id_y
monthTFuser_id_xuser_id_ynewper
01997-01-01True709378460.904028
11997-02-01True857196330.889754
21997-03-01True815495240.856153

RFM

rfm = df.pivot_table(index='user_id',
                    values={'order_products','order_dt','order_amount'},
                    aggfunc={'order_dt':'max',
                            'order_amount':'sum',
                            'order_products':'sum'})
user_idorder_amountorder_dtorder_products
111.771997-01-011
289.001997-01-126
3156.461998-05-2816
rfm['R'] = -(rfm.order_dt-rfm.order_dt.max())/np.timedelta64(1,'D')
rfm.rename(columns={'order_products':'F','order_amount':'M'},inplace='True')
rfm[['R','F','M']].apply(lambda x:x-x.mean())
user_idRFM
1177.778362-6.122656-94.310426
2166.778362-1.122656-17.080426
3-334.2216388.87734450.379574
def rfm_func(x):
    level = x.apply(lambda x:'1' if x >= 0 else '0')
    label = level.R + level.F + level.M
    d = {
        '111':'重要价值客户',
        '011':'重要保持客户',
        '101':'重要挽留客户',
        '001':'重要发展客户',
        '110':'一般价值客户',
        '010':'一般保持客户',
        '100':'一般挽留客户',
        '000':'一般发展客户',
    }
    result = d[label]
    return result

rfm['label'] = rfm[['R','F','M']].apply(lambda x:x-x.mean()).apply(rfm_func,axis=1)
rfm.groupby('label').agg(['sum','count'])
MFR
labelsumcountsumcountsumcount
一般价值客户7181.28776507736295.077
一般保持客户19937.45206171220629448.0206
一般发展客户196971.233300139773300591108.03300
一般挽留客户438291.811407429346140746951815.014074
rfm.loc[rfm.label=='重要价值客户','color']='g'
rfm.loc[~(rfm.label=='重要价值客户'),'color']='r'
rfm.plot.scatter('F','R',c=rfm.color)

在这里插入图片描述
新、老、活跃、回流、流失

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] == 'unreg':
                    status.append('unreg')
                else:
                    status.append('unactive')
            else:
                status.append('unreg')
        # 若本月消费
        else:
            if len(status) == 0:
                status.append('new')
            else:
                if status[i-1]=='unactive':
                    status.append('return')
                elif status[i-1] == 'unreg':
                    status.append('new')
                else:
                    status.append('active')
    return pd.Series(status)

若本月没有消费
若之前是未注册,则依旧为未注册
若之前有消费,则为流失/不活跃
其他情况,为未注册

若本月有消费
若是第一次消费,则为新用户
若之前有过消费,且上个月为不活跃,则为回流
若上个月为未注册,则为新用户
除此之外,为活跃

purchase_sta = df_purchase.apply(active_status,axis=1)
purchase_sta_ct = purchase_sta.replace('unreg',np.NaN).apply(lambda x:pd.value_counts(x))
purchase_sta_ct.fillna(0).T
purchase_sta_ct.fillna(0).T.plot.area()

在这里插入图片描述

purchase_sta_ct.fillna(0).T.apply(lambda x:x/x.sum(),axis=1)
order_diff = grouped_user.apply(lambda x:x.order_dt-x.order_dt.shift())
# 周期描述
order_diff.describe()
# 周期分布
(order_diff / np.timedelta64(1,'D')).hist(bins=20)
# 生命周期描述
(user_life['max'] - user_life['min']).describe()
# 生命周期分布
((user_life['max'] - user_life['min'])/np.timedelta64(1,'D')).hist(bins=20)
# 生命周期分布
u_1=((user_life['max'] - user_life['min']).reset_index()[0]/np.timedelta64(1,'D'))
u_1[u_1>0].hist(bins=40)

4.复购率和回购率分析

  • 复购率
    • 自然月内,购买多次的用户占比
  • 回购率
    • 曾经购买过的用户在某一时期内的再次购买的占比
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))
def purchase_back(data):
    status = []
    for i in range(17):
        if data[i] == 1:
            if data[i+1] == 1:
                status.append(1)
            if data[i+1] == 0:
                status.append(0)
        else:
            status.append(np.NaN)
    status.append(np.NaN)
    return pd.Series(status)
purchase_b = df_purchase.apply(purchase_back,axis=1)
(purchase_b.sum()/purchase_b.count()).plot(figsize=(10,4))
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值