用户数据分析

第一部分:数据类型的处理(预处理)

  • 数据加载
  • 字段定义:
    1. user_id:用户ID
    2. order_dt:购买日期
    3. order_product:购买产品的数量
    4. order_amount:购买金额
  • 观察数据
  • 查看数据的数据类型
  • 数据中是否存在缺失值
  • 将order_dt转换成时间类型
  • 查看数据的统计描述
    1. 计算所有用户购买商品的平均数量
    2. 计算所有用户购买商品的平均花费

在源数据中添加一列表示月份:astype(‘datetime64[M]’)

import pandas as pd
import numpy as np
from pandas import DataFrame,Series
import matplotlib.pyplot as plt
df=pd.read_csv('./CDNOW_master.txt',header=None,sep='\s+',names=['user_id','order_dt','order_product','order_amount'])
#'sep=\s+'表示用N多个空格进行分割数据
#names属性填充列索引名称
df.info() #查看是否存在缺失数据

用户数据分析
#将order_dt 转换成时间类型
df['order_dt']=pd.to_datetime(df['order_dt'],format='%Y%m%d')
df.info()

用户数据分析
#查看数据的统计描述
df.describe()  #转换成时间类型的数据不能参与到数值计算,所以只有显示剩余3列的结果

用户数据分析
#基于order_dt取出其中的月份
df['order_dt'].astype('datetime64[M]')
#在源数据中添加一列表示月份:astype('datetime64[M]')
df['month']=df['order_dt'].astype('datetime64[M]')  #将order_dt这列时间类型用astype('datetime64[M]')修改为月份
df.head()

用户数据分析

第二部分:按月数据分析

#用户每月花费的总金额
every_month_amount=df.groupby(by='month')['order_amount'].sum()
every_month_amount.plot()

用户数据分析
#所有用户每月的产品购买量
df.groupby(by='month')['order_product'].sum().plot()

用户数据分析
#所有用户每月消费的总次数(原始数据中每一行都代表1次消费记录)
df.groupby(by='month')['user_id'].count()   #count按月分组后计数消费记录的次数

用户数据分析
#统计每月消费的人数(可能同1天1个用户会消费多次)
df.groupby(by='month')['user_id'].unique()  #按月分组后unique()去除重复记录,消除1天1个用户多次消费的记录
df.groupby(by='month')['user_id'].nunique() # nunique 表示统计去重后的个数,是以数组形式(numpy.ndarray)返回列的所有唯一值

用户数据分析

第三部分:用户个体消费数据分析

3.1 用户消费总金额和消费的总次数的统计描述

#每个用户消费总金额
df.groupby(by='user_id')['order_amount'].sum()
#每个用户消费的总次数
df.groupby(by='user_id')['order_dt'].count()
#用户消费金额和消费产品数量的散点图
user_amount_sum =df.groupby(by='user_id')['order_amount'].sum()
user_prount_sum = df.groupby(by='user_id')['order_product'].sum()
plt.scatter(user_amount_sum,user_prount_sum)
#各个用户消费的总金额的直方图(消费金额在1000以内的分布)
df.groupby(by='user_id').sum().query('order_amount <= 1000')['order_amount'] #query()过滤器 ,只能用于dataframe类型的数据 ###pandas的query()方法是基于dataframe列的计算代数式,对于按照某列的规则进行过滤的操作,可以使用query方法。< code></=>

用户数据分析
df.groupby(by='user_id').sum().query('order_amount <= 1000')['order_amount'].hist()< code></=>

用户数据分析
#&#x5404;&#x4E2A;&#x7528;&#x6237;&#x6D88;&#x8D39;&#x7684;&#x603B;&#x6570;&#x91CF;&#x7684;&#x76F4;&#x65B9;&#x56FE;&#x5206;&#x5E03;&#x60C5;&#x51B5;&#xFF08;&#x6D88;&#x8D39;&#x5546;&#x54C1;&#x7684;&#x6570;&#x91CF;&#x5728;100&#x6B21;&#x4EE5;&#x5185;&#x7684;&#x5206;&#x5E03;&#xFF09;
df.groupby(by='user_id').sum().query('order_product <= 100')['order_product'].hist()< code></=>

用户数据分析

第四部分:用户消费行为分析

#&#x7528;&#x6237;&#x7B2C;&#x4E00;&#x6B21;&#x6D88;&#x8D39;&#x7684;&#x6708;&#x4EFD;&#x5206;&#x5E03;&#x548C;&#x4EBA;&#x6570;&#x7EDF;&#x8BA1;
#&#x7B2C;&#x4E00;&#x6B21;&#x6D88;&#x8D39;&#x7684;&#x6708;&#x4EFD;&#xFF1A;&#x6BCF;&#x4E00;&#x4E2A;&#x7528;&#x6237;&#x6D88;&#x8D39;&#x6708;&#x4EFD;&#x7684;&#x6700;&#x5C0F;&#x503C;&#x5C31;&#x662F;&#x8BE5;&#x7528;&#x6237;&#x7B2C;&#x4E00;&#x6B21;&#x6D88;&#x8D39;&#x7684;&#x6708;&#x4EFD;
df.groupby(by='user_id')['month'].min()
df.groupby(by='user_id')['month'].min().value_counts()   #&#x4EBA;&#x6570;&#x7684;&#x7EDF;&#x8BA1;
df.groupby(by='user_id')['month'].min().value_counts().plot()

用户数据分析
#&#x7528;&#x6237;&#x6700;&#x540E;1&#x6B21;&#x6D88;&#x8D39;&#x7684;&#x65F6;&#x95F4;&#x5206;&#x5E03;&#x548C;&#x4EBA;&#x6570;&#x7EDF;&#x8BA1;
#&#x7528;&#x6237;&#x6D88;&#x8D39;&#x6708;&#x4EFD;&#x7684;&#x6700;&#x5927;&#x503C;&#x5C31;&#x662F;&#x7528;&#x6237;&#x6700;&#x540E;&#x4E00;&#x6B21;&#x6D88;&#x8D39;&#x7684;&#x6708;&#x4EFD;
df.groupby(by='user_id')['month'].max()
df.groupby(by='user_id')['month'].max().value_counts()
df.groupby(by='user_id')['month'].max().value_counts().plot()  #&#x6839;&#x636E;&#x6298;&#x7EBF;&#x56FE;&#x53EF;&#x4EE5;&#x89C2;&#x5BDF;&#x7528;&#x6237;&#x5728;1-3&#x6708;&#x4EFD;&#x6D41;&#x5931;&#x7387;&#x8F83;&#x9AD8;

用户数据分析

新老用户的占比

  • 消费1次为新用户,消费多次为老用户

如何获知用户是否为第一次消费?可以根据用户的消费时间进行判定,如果第一次消费和最后一次消费时间一样则为新用户,否则是老用户

  1. 方法一:用value_counts统计 对应关系:True–新用户 ,False–老用户
(df.groupby(by='user_id')['order_dt'].min()==df.groupby(by='user_id')['order_dt'].max()).value_counts()

用户数据分析
2. 方法二:用agg函数,对分组后的结果进行多种指定形式的聚合
new_old_user_df=df.groupby(by='user_id')['order_dt'].agg(['min','max'])
new_old_user_df['min']==new_old_user_df['max']  #&#x6BD4;&#x8F83;&#x7528;&#x6237;&#x7684;&#x7B2C;&#x4E00;&#x6B21;&#x6D88;&#x8D39;&#x548C;&#x6700;&#x540E;1&#x6B21;&#x6D88;&#x8D39;&#x7684;&#x65F6;&#x95F4;&#x662F;&#x5426;&#x76F8;&#x7B49;&#xFF0C;True&#x4E3A;&#x65B0;&#x7528;&#x6237;&#xFF0C;Flase&#x4E3A;&#x8001;&#x7528;&#x6237;
(new_old_user_df['min']==new_old_user_df['max']).value_counts()

用户数据分析
3. 方法三:用reset_index方法将新老用户的统计结果看成新的DataFrame,再分别统计两者的人数
f=df.groupby(by='user_id')['order_dt'].min()==df.groupby(by='user_id')['order_dt'].max() #&#x5224;&#x65AD;&#x54EA;&#x4E9B;&#x662F;&#x65B0;&#x7528;&#x6237;,&#x65B0;&#x7528;&#x6237;&#x5BF9;&#x5E94;&#x7684;&#x503C;&#x4E3A;True
df_user=f.reset_index()   #&#x5C06;&#x539F;&#x6709;&#x7684;&#x7D22;&#x5F15;user_id&#xFF0C;&#x4F5C;&#x4E3A;&#x65B0;&#x7684;&#x4E00;&#x5217;&#x5E76;&#x5165;DataFrame&#x4E2D;
df_user['order_dt']==True
new_user=df_user.loc[df_user['order_dt']==True]['user_id'].count()   #&#x7EDF;&#x8BA1;&#x65B0;&#x7528;&#x6237;&#x7684;&#x4EBA;&#x6570;
old_user=df_user.loc[df_user['order_dt']==False]['user_id'].count()  #&#x7EDF;&#x8BA1;&#x8001;&#x7528;&#x6237;&#x7684;&#x4EBA;&#x6570;
print('new_user:',new_user)
print('old_user:',old_user)

用户数据分析
4. 根据价值分层,将用户分为:
  • 重要价值客户
  • 重要保持客户
  • 重要挽留客户
  • 重要发展客户
  • 一般价值客户
  • 一般保持客户
  • 一般挽留客户
  • 一般发展客户

RFM模型设计

通过三个指标来衡量该客户的价值状况

  • R 最近一次消费的时间间隔 (Recency) 上一次消费离得越近,也就是R的值越小,用户价值越高。
  • F 消费频率 (Frequency) 是指用户一段时间内消费了多少次 ,F值越大表示用户购买的越频繁,用户价值越高
  • M 消费金额 (Monetary) 消费金额越高,M值越大,表示客户的价值越高

分析得出每个用户的总购买量和总消费金额and最近1次消费的时间的表格rfm

rfm = df.pivot_table(index='user_id',aggfunc={'order_product':'sum','order_amount':'sum','order_dt':'max'})
#R &#x8868;&#x793A;&#x7528;&#x6237;&#x6700;&#x8FD1;1&#x6B21;&#x6D88;&#x8D39;&#x7684;&#x65F6;&#x95F4;&#x95F4;&#x9694;
max_dt=df['order_dt'].max() #&#x4ECA;&#x5929;&#x7684;&#x65E5;&#x671F;
#&#x6BCF;&#x4E2A;&#x7528;&#x6237;&#x6700;&#x540E;&#x4E00;&#x6B21;&#x4EA4;&#x6613;&#x7684;&#x65F6;&#x95F4;
user_last_dt=df.groupby(by='user_id')['order_dt'].max()
#&#x65F6;&#x95F4;&#x95F4;&#x9694;
(max_dt - user_last_dt)/np.timedelta64(1,'D')   #np.timedelta64&#x7528;&#x4E8E;&#x63A7;&#x5236;&#x65F6;&#x95F4;&#x95F4;&#x9694;
rfm['R'] = (max_dt - user_last_dt)/np.timedelta64(1,'D')
rfm.drop(labels='order_dt',axis=1,inplace=True)  #&#x5220;&#x9664;'order_dt'&#x8FD9;&#x5217;
rfm.columns=['M','F','R']
rfm

用户数据分析
'''rfm.apply(lambda x :x -x.mean()) #axis&#x9ED8;&#x8BA4;&#x4E3A;0&#xFF0C;&#x8868;&#x793A;&#x6848;&#x5217;&#x8BA1;&#x7B97;
#apply&#x51FD;&#x6570;&#x7528;&#x4E8E;DataFrame,&#x5BF9;&#x5B83;&#x7684;&#x884C;&#x6216;&#x5217;&#x8FDB;&#x884C;&#x64CD;&#x4F5C;
&#x76F8;&#x5F53;&#x4E8E;Series&#x7C7B;&#x578B;&#x91CC;&#x7684;map&#x51FD;&#x6570;
'''
def rfm_func(x):
    #&#x5B58;&#x50A8;&#x7684;&#x662F;&#x4E09;&#x4E2A;&#x5B57;&#x7B26;&#x4E32;&#x5F62;&#x5F0F;&#x7684;0&#x6216;1
    level = x.map(lambda x :'1' if x >= 0 else '0')
    label = level.R + level.F + level.M
    d = {
        '111':'&#x91CD;&#x8981;&#x4EF7;&#x503C;&#x5BA2;&#x6237;',
        '011':'&#x91CD;&#x8981;&#x4FDD;&#x6301;&#x5BA2;&#x6237;',
        '101':'&#x91CD;&#x8981;&#x633D;&#x7559;&#x5BA2;&#x6237;',
        '001':'&#x91CD;&#x8981;&#x53D1;&#x5C55;&#x5BA2;&#x6237;',
        '110':'&#x4E00;&#x822C;&#x4EF7;&#x503C;&#x5BA2;&#x6237;',
        '010':'&#x4E00;&#x822C;&#x4FDD;&#x6301;&#x5BA2;&#x6237;',
        '100':'&#x4E00;&#x822C;&#x633D;&#x7559;&#x5BA2;&#x6237;',
        '000':'&#x4E00;&#x822C;&#x53D1;&#x5C55;&#x5BA2;&#x6237;'
    }
    result = d[label]
    return result
#df.apply(func):&#x53EF;&#x4EE5;&#x5BF9;df&#x4E2D;&#x7684;&#x884C;&#x6216;&#x5217;&#x8FDB;&#x884C;&#x67D0;&#x79CD;&#xFF08;func)&#x5F62;&#x5F0F;&#x7684;&#x8FD0;&#x7B97;
rfm['label'] = rfm.apply(lambda x :x -x.mean()).apply(rfm_func,axis = 1)
rfm.head()

用户数据分析

第五部分:用户的生命周期

#&#x7EDF;&#x8BA1;&#x6BCF;&#x4E2A;&#x7528;&#x6237;&#x6BCF;&#x4E2A;&#x6708;&#x7684;&#x6D88;&#x8D39;&#x6B21;&#x6570;
user_month_count_df = df.pivot_table(index='user_id',values='order_dt',aggfunc='count',columns='month').fillna(0)
#&#x7EDF;&#x8BA1;&#x6BCF;&#x4E2A;&#x7528;&#x6237;&#x6BCF;&#x4E2A;&#x6708;&#x662F;&#x5426;&#x6D88;&#x8D39;,&#x6D88;&#x8D39;&#x8BB0;&#x5F55;&#x4E3A;1&#x5426;&#x5219;&#x8BB0;&#x4E3A;0
df_purchase = user_month_count_df.applymap(lambda x:1 if x >= 1 else 0)  #apply.map&#x5BF9;DataFrame&#x91CC;&#x7684;&#x6BCF;&#x4E00;&#x4E2A;&#x5143;&#x7D20;&#x8FDB;&#x884C;&#x64CD;&#x4F5C;
df_purchase

用户数据分析
#&#x5C06;df_purchase&#x4E2D;&#x7684;&#x539F;&#x59CB;&#x6570;&#x636E;0&#x548C;1&#x4FEE;&#x6539;&#x4E3A;new,unactive......,&#x8FD4;&#x56DE;&#x65B0;&#x7684;df&#x53EB;&#x505A;df_purchase_new
#&#x56FA;&#x5B9A;&#x7B97;&#x6CD5;
def active_status(data):
    status = [] #&#x67D0;&#x4E2A;&#x7528;&#x6237;&#x6BCF;&#x4E2A;&#x6708;&#x7684;&#x6D3B;&#x8DC3;&#x5EA6;
    for i in range(18):
        #&#x82E5;&#x672C;&#x6708;&#x6CA1;&#x6709;&#x6D88;&#x8D39;
        if data[i] == 0:
            if len(status)> 0:
                if status[i-1] =='unreg':
                    status.append('unreg')
                else:
                    status.append('unactive')
            else:
                status.append('unreg')

        #&#x82E5;&#x672C;&#x6708;&#x6D88;&#x8D39;
        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
pivoted_status = df_purchase.apply(active_status,axis = 1)
pivoted_status.head()

用户数据分析
pivoted_status.values.tolist()
df_purchase_new = DataFrame(data=pivoted_status.values.tolist(), index=df_purchase.index, columns=df_purchase.columns)
df_purchase_new

用户数据分析
#&#x6BCF;&#x6708;&#x3010;&#x4E0D;&#x540C;&#x6D3B;&#x8DC3;&#x3011;&#x7528;&#x6237;&#x7684;&#x8BA1;&#x6570;
purchase_status_ct = df_purchase_new.apply(lambda x :pd.value_counts(x)).fillna(0) #&#x6309;&#x5217;&#x628A;&#x4E0D;&#x540C;&#x7684;&#x503C;&#x8FDB;&#x884C;&#x5206;&#x7EC4;&#x7EDF;&#x8BA1;
purchase_status_ct.T   #T&#x8F6C;&#x7F6E;

用户数据分析

Original: https://blog.csdn.net/qq_42119837/article/details/123157998
Author: Lucky20171225
Title: 用户数据分析

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/739771/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球