数据蛙强化课程第一期

CD店铺消费者消费数据分析

2019-02-17  本文已影响4人  曾立韬
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

plt.rcParams['font.family'] = ['Arial Unicode MS'] 

pd.__version__

columns=['user_id','order_dt','order_products','order_amount']
df = pd.read_csv('CDNOW_master.txt',names=columns,sep='\s+')
#如果数据本身以空格做分割的话,这里sep要用\s+

df.order_dt=pd.to_datetime(df.order_dt,format='%Y%m%d')

df['month']=df.order_dt.values.astype('datetime64[M]')
#后续要解决的问题都需要以月为单位来计算,因此要多加一条column:"month",以月为单位。

df.head(10)

df.describe()



接下来就开始进行进一步的分析。

首先:1.进行用户按月消费趋势的分析。分别有:

grouped_month=df.groupby('month') 

grouped_month.order_amount.sum().plot()#(1)每月消费的总金额

grouped_month.order_products.count().plot()#(2)每月的消费次数

grouped_month.order_products.sum().plot()#(3)每月的产品购买数

grouped_month.user_id.count().plot()#(4)每月消费人数




2.用户个体消费分析


grouped_user=df.groupby("user_id")

grouped_user.sum().describe() #(1)用户消费金额、产品购买数的描述统计。

grouped_user.sum().plot.scatter(x='order_amount',y='order_products',c='b')

grouped_user.sum().query('order_amount<3000').query('order_products<200').plot.scatter(x='order_amount',y='order_products',c='b')
(2)用户消费金额和产品购买数的散点图

grouped_user.sum().query('order_amount<1000').order_amount.plot.hist(bins=50)
#(3)用户消费金额的分布图(根据上面散点图,选择数据较为集中的部分进行分析。)

grouped_user.sum().query('order_products<100').order_products.plot.hist(bins=50)
#(4)用户消费产品数的分布图(根据上面散点图,选择数据较为集中的部分进行分析)

user_cumsum=grouped_user.sum().sort_values('order_amount').apply(lambda x:x.cumsum()/x.sum())

user_cumsum.reset_index().order_amount.plot()



3.用户消费行为:


grouped_user.min().order_dt.value_counts().plot(figsize=(10,4))
#第一次购买的时间,就是时间最小,所以用.min()。然后用value_counts()汇总起来。 

grouped_user.max().order_dt.value_counts().plot()
#最后一次消费,日期最大。

(grouped_user.order_dt.count()==1).value_counts()

user_life=grouped_user.order_dt.agg(['min']).sort_values('min')
user_life['month']=user_life['min'].values.astype('datetime64[M]')
user_life.groupby('month').month.describe()

rfm=df.pivot_table(index='user_id',
                          values=['order_products','order_amount','order_dt'],
                          aggfunc={'order_dt':'max',
                                  'order_amount':'sum',
                                  'order_products':'count'})
rfm.head()

利用透视表功能,把user_id作为索引,根据order_amount和order_dt的值,算出每个用户最大购买日期(最后一次消费的日期)、总消费金额,以及总消费次数(这里用 'order_products':'count' 或者 'order_amout':'count'都一样,因为算的是次数而不是购买的产品数。每次消费买的产品数都可能不一样。)然后我们可以看下rfm表大概长啥样:



rfm["R"]=(rfm.order_dt.max()-rfm.order_dt)/np.timedelta64(1,'D')
rfm=rfm.rename(columns={'order_products':'F','order_amount':'M'})

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' : '重要挽留客户',         
         '110' : '一般价值客户',
         '001' : '重要发展客户',
         '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.head(10)

rfm_grouped=rfm.groupby('label') 
rfm_grouped.sum()

pd.Series(rfm_grouped['label'].count(),name='series')
pd.Series(rfm_grouped['label'].count(),name='series').plot.pie()

② 用户生命周期:新、活跃、回流、流失(不活跃)

pivoted_counts = df.pivot_table(index='user_id', # 使用数据透视,将每个用户每月消费次数计算出来
                               columns='month', # 如果没有数据的话(比如1号客户1997年2月1日没有数据),数据透视功能也会把它变成NaN。
                               values='order_dt',# 因此要价格fillna(0)把空值变成0。
                               aggfunc='count').fillna(0)
pivoted_counts.head()
purchase=pivoted_counts.applymap(lambda x:1 if x>0 else 0)
def active_status(data):
    status=[]
    for i in range(18): #共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 status

函数的逻辑:

若本月没有消费:
若本月有消费:
indexs=df['month'].sort_values().astype('str').unique()
purchase_sta=purchase.apply(lambda x:pd.Series(active_status(x),index=indexs),axis=1)
purchase_sta.head()
purchase_sta.replace('unreg',np.NaN).apply(lambda x:pd.value_counts(x)).fillna(0).T
purchase_sta.replace('unreg',np.NaN).apply(lambda x:pd.value_counts(x)).fillna(0).T.plot.area(figsize=(10,4))

(5)用户购买周期(按订单)
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)

订单周期呈指数分布。
用户的平均购买周期是68天。
绝大部分用户的购买周期都低于100天。


① 用户消费周期描述

(user_life['max']-user_life['min']).describe()

② 用户消费周期分布

((user_life['max']-user_life['min'])/np.timedelta64(1,'D')).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 status  
purchase_b=purchase.apply(lambda x:pd.Series(purchase_back(x),index=indexs),axis=1)
purchase_b.head()
(purchase_b.sum()/purchase_b.count()).plot(figsize=(10,4))
上一篇 下一篇

猜你喜欢

热点阅读