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天短信推送。
CD数据分析
最新推荐文章于 2024-07-07 22:26:27 发布