CD数据分析

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

%matplotlib inline
plt.style.use('ggplot')

columns = ['UID','order_dt','product','amount']
df = pd.read_csv(r'C:\Users\shanminghuo\Desktop\python\CDNOW_master.txt',encoding = 'gb2312',names = columns, sep='\s+')
df.head()

df.describe()
df['date'] = pd.to_datetime(df.order_dt,format='%Y%m%d')
df['month'] = df.date.values.astype('datetime64[M]') #日期格式转换
df.head()
user_group = df.groupby('UID').sum()
user_group.head()

df.groupby('month').amount.sum().plot()   #看月销售情况;默认plot()为折线图;根据哪个指标聚合、图表呈现哪个指标、统计方式如何、选用哪个类型图表
df.groupby('UID').sum().plot.scatter(x='amount',y='product') #选择不同的数据呈现形式 plot.+图表函数

plt.figure(figsize=(12,4))  #设置一个宽12,高4的画图区域
plt.subplot(121)
df.amount.hist(bins=30)
plt.subplot(122)
df.groupby('UID').amount.sum().hist(bins=30) #金额分布情况

df.groupby('UID').month.min().value_counts()#计算第一次消费的用户月分布情况;先按UID聚合,再按月分组,并计算月份最小值并计数
df.groupby('UID').month.max().value_counts() #计算最后一次消费的用户月分布情况

pivot_count = df.pivot_table(index='UID', columns='month', values='amount', aggfunc='count').fillna(0)
columns_month = df.month.sort_values().astype('str').unique() #df.sort_values('UID',ascending=False),根据UID降序排列
pivot_count.columns = columns_month
pivot_count.head()
#一个透视表,规范一下日期格式

#apply运用于DataFrame中的行或列,applymap运用于整个DataFrame,其中参数axis=0,作用于列,axis=1,作用于行
#lambda 传入的参数:返回的计算表达式
pivot_count_transf = pivot_count.applymap(lambda x:1 if x>1 else (0 if x==1 else np.NaN)) #格式有点特别,传入参数x,如果x>1,取值为1,如果x=1,取值为0,其余显示NaN
pivot_count_transf.head()
(pivot_count_transf.sum()/pivot_count_transf.count()).plot(figsize=(10,4)) #复购率:在某时间范围内消费2次以上用户占总消费用户比重

pivot_count_return = pivot_count.applymap(lambda x:1 if x>0 else 0) #有过消费记录记为1,没有则记0
pivot_count_return.head() 
def purchase_return(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 status

pcr = pivot_count_return.apply(purchase_return, axis=1) #不能用applymap,需要作用于行方向
pcr.head()
(pcr.sum()/pcr.count()).plot(figsize=(10,4))  #回购率:在某一个时间区间内消费过的用户,在下个时间区间内还消费过的用户占总消费用户比重


def active_status(data):
    status=[]
    for i in range(18):
        if data[i]>0:  #如果当月有消费
            if len(status)==0:
                status.append('new')
            else:
                if status[i-1]=='unactive':
                    status.append('return')
                else:
                    if status[i-1]=='none':
                        status.append('new')
                    else:
                        status.append('active')
        else:
            if len(status)==0:
                status.append('none')
            else:
                if status[i-1]=='none':
                    status.append('none')
                else:
                    status.append('unactive')
    return status
df_active = pivot_count.apply(active_status,axis=1)
df_active.head()  #用户分类
df_active_count = df_active.replace('none',np.NaN).apply(lambda x:pd.value_counts(x)).fillna(0)
df_active_count.head()
df_active_count.T.plot.area()
df_active_count = df_active.replace('none',np.NaN).replace('unactive',np.NaN).apply(lambda x:pd.value_counts(x)).fillna(0)
df_active_count.T.plot.area(figsize=(12,4))

df_active_count_per = df_active_count.apply(lambda x:x/x.sum(),axis=1) 
df_active_count_per.ix['active'].plot(figsize=(12,4))  
#loc——通过行标签索引行数据,iloc——通过行号索引行数据 ,ix——通过行标签或者行号索引行数据
#df.ix[:,['c']],取c列
df_active_count_per.loc['return'].plot(figsize=(12,4))

date_min = df.groupby('UID').date.min()
date_max = df.groupby('UID').date.max()
(date_max-date_min).head(10)   #用户生命周期=最后一次消费日期-第一次消费日期
(date_max-date_min).describe()
lifetime = (date_max-date_min).reset_index()
lifetime.head()
lifetime['LT']=lifetime.date/np.timedelta64(1,'D')  #因为date列数据类型为Timedelta,所以再除这个函数转化为数值,(1,'D')表示1天的单位
lifetime[lifetime.LT>0].LT.hist(bins=120,figsize=(10,4))  #LT数值大于0的做一个直方图(即生命周期分布)
lifetime[lifetime.LT>0].LT.mean()
lifetime[lifetime.LT>0].LT.mean()/lifetime.LT.mean()  #消费2次以上的用户生命周期是消费1次的用户生命周期的2.04倍

#计算留存
df_retention = pd.merge(left=df,right=date_min.reset_index(),how='inner',on='UID',suffixes=('','_min')) #date_min中是按UID聚合,取最小订单日期,这里再根据UID合并两个数据,取到每个用户最小订单日期,但一定要加.reset_index(),重置索引
df_retention.head(10)
df_retention['date_diff'] = df_retention.date-df_retention.date_min
df_retention['date_diffs'] = df_retention.date_diff.apply(lambda x: x/np.timedelta64(1,'D')) #timedelta64类型是numpy库的一部分
df_retention.head()

bin = [0,3,7,15,30,60,90,180,365]
df_retention['date_bin'] = pd.cut(df_retention.date_diffs,bins=bin)
df_retention.head(10)
df_re = df_retention.pivot_table(index = 'UID',columns = 'date_bin',values='amount',aggfunc=sum) #用户在第一次消费后,在后续各时间段内的消费总额
df_re.head()
df_re.mean()
df_re_t = df_re.fillna(0).applymap(lambda x: 1 if x>0 else 0) #在不同的时段,消费大于1次的被标记为1(已除去了第一次消费)
df_re_t.head()
(df_re_t.sum()/df_re_t.count()).plot.bar()  #CD消费不是高频消费,但要在一定时间内召回用户

def diff(group):
    d = group.date_diffs.shift(-1)-group.date_diffs  #date_diffs.shift(-1)表示这列数据整体上移一行,这个公式表示用户下一次消费距上一次消费的时间间隔
    return d

last_diff = df_retention.groupby('UID').apply(diff)
last_diff.head()
last_diff.mean()  #用户平均消费时间间隔为69天

last_diff.hist(bins=15)   #这个图最直观,虽然CD消费不是高频行为,但绝大部分用户消费时间间隔在1-2个月,建议:不妨将时间召回点设为消费后立即赠送优惠券,消费后10天询问用户CD怎么样,消费后30天提醒优惠券到期,消费后60天短信推送。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值