首页 > 其他分享 >【数据分析】RFM会员价值度模型详解:大案例解析(第28天)

【数据分析】RFM会员价值度模型详解:大案例解析(第28天)

时间:2024-07-07 11:31:09浏览次数:3  
标签:buy pv cust 28 详解 rfm data id RFM

系列文章目录

  1. RFM会员价值度模型分析
  2. 用户行为分析

文章目录


前言

本文通过RFM会员价值度模型分析案例,用户行为分析案例,详解了工作中数据分析流程。

1 RFM会员价值度模型分析案例

1.1 RFM会员价值度模型概念

  • 根据会员的价值度对会员分群的模型
  • 会员有了不同群体之后可以实现对不同群体的用户使用不同的营销策略
  • 三个维度指标
    • R -> recency 最近一次消费时间距当前的天数差值, R值越小, 价值度越高
    • F -> frequency 一段时间内消费次数, F值越大, 价值度越高
    • M -> monetary 一段时间内消费总金额, M值越大, 价值度越高
  • 使用场景
    • 交易行为的业务 -> 一般就是发生买卖
    • 电商
    • 旅游 -> 最近一次旅游时间, 一段时间内旅游次数, 消费金额
    • 抖音/快手/斗鱼/… -> 最近一次登录时间, 一段时间内登录次数, 分享/点赞/评论

1.2 RFM会员价值度模型实现流程

  • 获取一段时间内的数据集, 会员id, 订单时间, 订单金额; 一个会员可能对应多笔订单, 结果是以会员id为维度进行分组计算
  • 计算R/F/M的原始值
    • R -> 当前日期时间 - 用户最大订单时间, R越小越好
    • F -> 一段时间内, 订单次数, 根据会员id分组, 统计次数 F越大越好
    • M ->一段时间内, 订单总金额, 根据会员id分组, 统计订单总金额 M越大越好
  • 分别对R/F/M三个维度划分区间 -> 打上价值分 1~5分
    • 业务情况 -> 专家模型(专家根据自己的主观意愿进行分析)
    • 中位数/均值
    • 二八原则 -> 20%的人掌握了80%的财富, 考虑quantile
  • 对R/F/M三个维度的价值分进行进一步的划分, 减少分类数
    • 均值/中位值
  • 对用户进行分群
    • 三个维度值进行字符串拼接 111, 112, 113, …
    • 三个维度值求和, 会员总价值分

1.3 RFM案例代码实现

  • 加载数据集

    import time  # 时间库
    import numpy as np  # numpy库
    import pandas as pd  # pandas库
    from pyecharts.charts import Bar3D # 3D柱形图
    
    # 加载5个sheet页中的df数据, 保存到列表中
    sheet_names = ['2015','2016','2017','2018','会员等级']
    sheet_datas = [pd.read_excel('./data/sales.xlsx', sheet_name=i) for i in sheet_names]
    for i in sheet_names:
        print(i)
    
    df1 = pd.read_excel('data/sales.xlsx', sheet_name='2015')
    df1.head()
    # [df1, df2, df3, df4, df5]
    sheet_datas
    
  • 查看数据集基本情况

    # 查看数据基本情况
    # 查看描述统计指标
    df1.describe()
    # 统计包含缺失值的行数
    # any():判断每列中是否包含True值 -> 缺失值  axis=1:按行
    df1.isnull().any(axis=1).sum()
    # 查看每列的数据类型
    df1.dtypes
    list(zip(['a','b', 'c'], [1, 2, 3]))
    for i in zip(['a','b', 'c'], [1, 2, 3]):
        print(i)
        
    # 元组拆包后进行循环遍历
    for a, b in zip(['a','b', 'c'], [1, 2, 3]):
        print(a)
        print(b)
        
    # 对5个df的列表和表名列表循环遍历
    for each_name, each_data in zip(sheet_names, sheet_datas):    
        print('[data summary for ============={}===============]'.format(each_name))
        print('Overview:','\n',each_data.head(4))# 展示数据前4条
        print('DESC:','\n',each_data.describe())# 数据描述性信息
        # any(axis=1):每行是否有缺失值, 返回True或False
        print('NA records',each_data.isnull().any(axis=1).sum()) # 包含缺失值条目数    
        print('Dtypes',each_data.dtypes) # 数据类型
    
  • 数据处理

    # 合并保存df列表中的前4个df -> 每年订单数据子集, 合并成一个df
    # 删除包含缺失值的行数据 2行数据
    # 过滤掉订单金额小于等于1的行数据
    # 新增一列每年最大提交日期列作为当前时间
    # 新增一列 每笔订单的提交日期和最大提交日期的 天数差值 ->计算R值
    
    # 合并保存df列表中的前4个df -> 每年订单数据子集, 合并成一个df
    # sheet_datas[:-1] -> 列表切片操作, 获取前4个元素
    # concat([df1, df2, ...])
    data_merge = pd.concat(sheet_datas[:-1])
    data_merge.info()
    
    # 删除包含缺失值的行数据 2行数据
    data_merge.dropna(inplace=True)
    data_merge.info()
    
    # 过滤掉订单金额小于等于1的行数据
    data_merge.query('订单金额 > 1', inplace=True)
    data_merge.info()
    
    # 新增一列 年份 列, 根据提交日期列获取年份
    data_merge['year'] = data_merge['提交日期'].dt.year
    data_merge.head()
    # 新增一列每年最大提交日期列作为当前时间
    # 根据年份列分组, 通过transform方法获取每组中的最大提交日期
    data_merge['max_year_date'] = data_merge.groupby(by='year')['提交日期'].transform(max)
    data_merge.head()
    
    # 新增一列 每笔订单的提交日期和最大提交日期 的天数差值 ->计算R值
    # .dt.days 获取天数差值列中的整数值
    data_merge['date_interval'] = (data_merge['max_year_date'] - data_merge['提交日期']).dt.days
    data_merge.head()
    
  • 计算rfm原始值

    # r -> 当前时间和最近提交日期的差值, 最近一次消费时间
    # f -> 每年消费订单数量
    # m -> 每年消费总金额
    
    # 是以年份和会员id维度进行分组 -> 需要获取不同年份不同会员的分群结果
    # 对不同列进行不同聚合操作 agg({列名1:聚合函数1, 列名2:聚合函数2, ...})
    # as_index=False:不保留分组列作为索引, 重置索引操作 -> reset_index()
    rfm_gb = data_merge.groupby(by=['year', '会员ID'],as_index=False).agg({'date_interval':min, '订单号': 'count', '订单金额': sum})
    rfm_gb.head()
    # 修改rfm_gb的列名,修改为r,f,m
    rfm_gb.rename(columns={'date_interval':'r', '订单号': 'f', '订单金额':'m'}, inplace=True)
    rfm_gb.head()
    
  • 划分rfm原始值区间

    # 分析rfm三列的描述统计指标
    rfm_gb[['r', 'f', 'm']].describe().T
    
    # 定义rfm划分区间
    # r和m -> (最小值-1, 1/4分位值] (1/4分位值, 3/4分位值] (3/4分位值, 最大值]
    # f -> (0, 2] (2,5] (5, 130]
    # 要包含划分区间的最小值, cut方法默认是左开右闭, 第一个值=min值-1
    r_bins = [-1, 79, 255, 365]
    f_bins = [0, 2, 5, 130]
    m_bins = [0, 69, 1199, 206252]
    
    # r的labels列表, -1:倒序
    [i for i in range(len(r_bins)-1, 0, -1)]
    [i for i in range(1, len(f_bins))]
    list1 =[]
    for i in range(1,10):
        list1.append(i)
    list1
    
    # 通过cut方法实现划分 打上1,2,3价值分
    # r ->(-1,79]为3分 (79, 255]为2分 (255, 365]为1分  相反对应
    # f/m 划分区间和分值对应
    # labels就是1,2,3分的分值
    # pd.cut(rfm_gb['r'], bins=r_bins, labels=[3, 2, 1])
    # pd.cut(rfm_gb['r'], bins=r_bins, labels=[1, 2, 3])
    rfm_gb['r_score'] = pd.cut(rfm_gb['r'], bins=r_bins, labels=[i for i in range(len(r_bins)-1, 0, -1)])
    rfm_gb['f_score'] = pd.cut(rfm_gb['f'], bins=f_bins, labels=[i for i in range(1, len(f_bins))])
    rfm_gb['m_score'] = pd.cut(rfm_gb['m'], bins=m_bins, labels=[i for i in range(1, len(m_bins))])
    rfm_gb
    
  • 根据rfm分值进行用户分群

    # r_score,f_score和m_score为类别类型列, 不能直接进行拼接操作
    rfm_gb['r_score'].astype('str') + rfm_gb['f_score'].astype('str') + rfm_gb['m_score'].astype('str')
    
    # 将类别类型列转换成字符串列
    rfm_gb['r_score'] = rfm_gb['r_score'].astype(np.str)
    rfm_gb['f_score'] = rfm_gb['f_score'].astype(np.str)
    rfm_gb['m_score'] = rfm_gb['m_score'].astype(np.str)
    # 字符串的拼接操作
    rfm_gb['rfm_group'] = rfm_gb['r_score'] + rfm_gb['f_score'] + rfm_gb['m_score']
    rfm_gb.head()
    

1.4 数据可视化

# 获取年份, 用户类别, 用户数量 三列
display_data = rfm_gb.groupby(by=['rfm_group', 'year'], as_index=False)['会员ID'].count()
display_data.head()
# 修改列名 会员ID改为number
display_data.rename(columns={'会员ID':'number'}, inplace=True)
display_data.head()

# 绘制3d柱状图
# 设置柱子的颜色
range_color = ['#313695', '#4575b4', '#74add1', '#abd9e9', '#e0f3f8', '#ffffbf',
               '#fee090', '#fdae61', '#f46d43', '#d73027', '#a50026']
# 设置左下方缩放条的最大值, 数据集中number列最大值
range_max = display_data['number'].max()
range_max

[i.tolist() for i in display_data.values]

from pyecharts.commons.utils import JsCode
import pyecharts.options as opts

c = (
    Bar3D()#设置了一个3D柱形图对象
    .add(
        "",#图例
        [d.tolist() for d in display_data.values],#数据
        xaxis3d_opts=opts.Axis3DOpts(type_="category", name='分组名称'),#x轴数据类型,名称,rfm_group
        yaxis3d_opts=opts.Axis3DOpts(type_="category", name='年份'),#y轴数据类型,名称,year
        zaxis3d_opts=opts.Axis3DOpts(type_="value", name='会员数量'),#z轴数据类型,名称,number
    )
    .set_global_opts( # 全局设置
        visualmap_opts=opts.VisualMapOpts(max_=range_max, range_color=range_color), #设置颜色,及不同取值对应的颜色
        title_opts=opts.TitleOpts(title="RFM分组结果"),#设置标题
    )
)
c.render_notebook() #在notebook中显示

1.5 案例结论

  • 通过3d柱状图得到一些结论

  • 通过代码得到一些结论

    # 通过代码得到一些结论
    # 统计每类用户占所有用户的比例
    rfm_percent = display_data.groupby(by='rfm_group', as_index=False)['number'].sum()
    # rfm_percent['number'].sum() ->计算number的求和
    # s对象和数值常数变量计算
    rfm_percent['count_per'] = rfm_percent['number'] / rfm_percent['number'].sum()
    # 匿名函数中的x值是s对象中的每个值
    rfm_percent['count_per'] = rfm_percent['count_per'].apply(lambda x: format(x, '.2%'))
    # 对number列进行降序
    rfm_percent.sort_values(by='number', ascending=False)
    

1.6 结果保存

  • 保存到excel中

    rfm_gb.to_excel('sales_rfm_score1.xlsx')  # 保存数据为Excel
    
  • 保存到数据库中

    # 需要安装pymysql,部分版本需要额外安装sqlalchemy
    # 导入sqlalchemy的数据库引擎
    from sqlalchemy import create_engine
    
    # 创建数据库引擎,传入uri规则的字符串
    engine = create_engine('mysql+pymysql://root:[email protected]:3306/test?charset=utf8')
    # mysql+pymysql://root:[email protected]:3306/test?charset=utf8
    # mysql 表示数据库类型
    # pymysql 表示python操作数据库的包
    # root:123456 表示数据库的账号和密码,用冒号连接
    # 192.168.88.100:3306/test 表示数据库的ip和端口,以及名叫test的数据库
    # charset=utf8 规定编码格式
    
    # df.to_sql()方法将df数据快速写入数据库
    rfm_gb.to_sql('rfm_gb', engine, index=False, if_exists='append')
    # 第一个参数为数据表的名称
    # 第二个参数engine为数据库交互引擎
    # index=False 表示不添加自增主键
    # if_exists='append' 表示如果表存在就添加,表不存在就创建表并写入
    

2 用户行为分析案例

2.1 用户行为分析概念

  • 获取用户在网站或app等平台的一些数据, 根据数据进行相关的统计和分析, 从而获得其中的一些规律/规则
  • 用户行为
    • 登录
    • 购买
    • 点击
    • 浏览
    • 加购物车
    • 转发
    • 收藏
    • 评论

2.2 如何进行用户行为分析

  • 事件分析 -> 研究某行为事件的发生对产品产生的影响以及影响程度
    • 4w1h
    • 谁在什么时间什么地点通过什么方式做了什么事情
    • 收集用户信息, who -> 用户id, 账号, session id
    • 收集各种事件, when -> 浏览事件, 点击时间, 下单时间, 支付时间, 完成时间, …
    • 收集地址, where -> ip解析地址, 收货地址
    • 收集事件, what -> 购买, 加购物, 点赞, …
    • 收集使用的方式, how -> app, 网站, 设备信息, 浏览器信息
  • 页面点击分析
    • 通过统计不同页面的指标, 对页面进行各种分析
    • pv -> 页面浏览次数
    • uv -> 页面访问人数
    • 页面内可点击次数
    • 页面内的访问人数
    • 占比
  • 漏斗模型分析
    • 统计各个阶段的转化率
    • 用于网站用户行为分析APP用户行为分析中,在流量监控产品目标转化等日常数据运营与数据分析工作
  • 用户行为路径分析
    • 通过用户访问app或网址的路径进行分析
    • 规定好访问页面或功能的顺序
    • 统计不同页面或功能中的一些转化率

2.3 代码实现

  • 数据处理

    # 导入模块
    import pandas as pd
    import numpy as np
    import matplotlib.pyplot as plt
    import time
    from datetime import datetime,timedelta,date
    import warnings
    warnings.filterwarnings('ignore')
    
    # 加载数据集
    df = pd.read_csv('data/customer_behavior.csv')
    df.head()
    
    # 去掉没有用的列 Unnamed: 0
    # 对day_id和buy_time列转换日期时间类型
    # 获取2019-11-05~2019-11-13的数据子集
    # 查看是否有缺失值的行数据, 删除
    # 提取日期时间列中的部分时间 date, time, hour, day, dayofweek
    
    # 去掉没有用的列 Unnamed: 0
    data = df.drop(labels=['Unnamed: 0'], axis=1)
    data.head()
    
    # 对day_id和buy_time列转换日期时间类型
    data['day_id'] = pd.to_datetime(df['day_id'])
    data['buy_time'] = data['buy_time'].astype('datetime64[ns]')
    data.info()
    
    # 获取2019-11-05~2019-11-13的数据子集
    data1 = data.query('buy_time>="2019-11-05" & buy_time<="2019-11-13"')
    data1.shape
    
    # 查看是否有缺失值的行数据, 删除
    data1.isnull().any(axis=1).sum()
    
    # 提取日期时间列中的部分时间 date, time, hour, day, dayofweek
    data1['month'] = data1['day_id'].dt.month
    data1['hours'] = data1['day_id'].dt.hour
    data1['times'] = data1['day_id'].dt.time
    # 默认获取0-6, +1->周一~周日
    data1['weekday'] = data1['day_id'].dt.dayofweek + 1
    data1.head()
    
  • 计算uv/pv/平均访问量/跳失率

    # 计算 pv/uv 数
    # 计算 平均访问量=pv/uv 
    # 计算 跳失率=只有点击行为的用户数/总用户数
    
    behavior_count = data1.groupby(by='be_type')['cust_id'].count()
    behavior_count
    # pv数 -> 页面点击次数, be_type列的值等于pv的条目数
    PV = behavior_count['pv']
    PV
    # uv数 -> 用户id进行去重之后的条目数
    UV = len(data1['cust_id'].unique())
    UV
    # 平均访问量
    avg_vist_number = round(PV / UV)
    avg_vist_number
    print('平均访问量为%d' % avg_vist_number)
    
    # 跳失率
    # 获取不同行为的数据的cust_id列 s对象
    # 点击
    data_pv = data1[data1['be_type']=='pv']['cust_id']
    # 收藏
    data_fav = data1[data1['be_type']=='fav']['cust_id']
    # 加购物车
    data_cart = data1[data1['be_type']=='cart']['cust_id']
    # 购买
    data_buy = data1[data1['be_type']=='buy']['cust_id']
    # 获取只有点击行为的用户数  pv->[1,2,3,4,5] fav->[1,2] cart->[1,3] buy->[1,4]  只有点击行为的用户为5
    # 获取唯一用户id的信息 转换成集合 去重操作
    # len(set(data_pv))
    # 集合作差 只有pv行为的用户id集合
    data_pv_only = set(data_pv) - set(data_fav) - set(data_cart) - set(data_buy)
    data_pv_only
    # 只有pv行为的用户数
    pv_only = len(data_pv_only)
    pv_only
    # 计算跳失率 以百分比形式保留2位小数
    str(round((pv_only / UV) * 100, 2)) + '%'
    
  • 按天数统计pv和uv数

    # 按天统计用户的pv数
    # 获取be_type=pv的数据子集
    pv_day_data = data1[data1['be_type']=='pv']
    pv_day_data.head()
    pv_day = pv_day_data.groupby(by='buy_time')['cust_id'].count()
    pv_day
    
    # 按天统计用户的uv数  uv数是去重的结果
    # 当前是统计每天的uv数  根据buy_time和cust_id去重后统计
    uv_day = pv_day_data.drop_duplicates(subset=['cust_id', 'buy_time']).groupby(by='buy_time')['cust_id'].count()
    uv_day
    
    # 数据可视化
    pv_day.plot()
    
    attr = pv_day.index
    v1 = pv_day.values
    v2 = uv_day.values
    # 将两个图绘制到一起
    #折线图绘制
    fig = plt.figure(figsize=(16,12))      
    plt.subplot(2,1,1)  
    xlabel=attr
    # x=range(len(xlabel)), y=v1
    plt.plot(range(len(xlabel)),v1)   
    plt.xticks(np.arange(9),'')  
    plt.title('日点击量趋势图')
    plt.ylabel('日pv') 
    for a,b in zip(range(len(xlabel)),v1):
        # plt.text(x,y,s): x,y为图形的x,y轴的值,s为给图形添加的文字,此时将pv数添加到折线图上展示
        plt.text(a, b, b, ha='center', va='bottom', fontsize=10) 
    plt.subplot(2,1,2)
    plt.plot(range(len(xlabel)),v2) 
    plt.xticks(np.arange(9),('11-05 周二','11-06 周三','11-07 周四','11-08 周五','11-09 周六','11-10 周日','11-11 周一','11-12 周二','11-13 周三'),rotation=45)
    plt.title('日独立访客数趋势图')
    plt.ylabel('日uv')
    for a,b in zip(range(len(xlabel)),v2):
        # plt.text(x,y,s): x,y为图形的x,y轴的值,s为给图形添加的文字,此时将uv数添加到折线图上展示
        plt.text(a, b, b, ha='center', va='bottom', fontsize=10)
    plt.show()
    
  • 按小时统计pv和uv数

    # 按小时统计pv数
    pv_hour = data1.groupby(by='hours', as_index=False)['cust_id'].count().rename(columns={'cust_id':'pv'})
    pv_hour
    
    # 按小时统计uv数
    uv_hour = data1.drop_duplicates(subset=['hours', 'cust_id']).groupby(by='hours', as_index=False)['cust_id'].count().rename(columns={'cust_id':'uv'})
    uv_hour
    
    # 数据可视化
    # sharex=True:多图共享x轴
    fig, axes = plt.subplots(2,1,sharex=True,figsize=(16,12))
    pv_hour.plot(x='hours',y='pv',ax=axes[0])
    uv_hour.plot(x='hours',y='uv',ax=axes[1])
    # 设置x轴的刻度值和刻度标签
    plt.xticks(range(24), np.arange(24))
    axes[0].set_title('按小时点击量趋势图')
    axes[1].set_title('按小时独立访客数趋势图')
    
  • 计算每天的n日留存率

    # 计算留存率
    # 留存率 = n日留存数 / 当天新用户数
    # 统计2019-11-05的3日留存, 2019-11-05新用户数, 统计2019-11-08留存用户数(11-05新用户中又登录的用户)
    # 定义一个空列表, 存储用户信息
    user=[]
    # 获取2019-11-05的数据子集
    data1[data1['buy_time']=='2019-11-05']['cust_id'].unique()
    # 获取2019-11-05的新用户数据
    new_user = set(data1[data1['buy_time']=='2019-11-05']['cust_id'].unique()) - set(user)
    # 将当天的所有用户添加到user列表中
    user.extend(new_user)
    # 获取3天之后的数据子集, 目的是获取用户数据
    # user_nday中既有前3天的用户,也有当天的新用户
    user_nday = data1[data1['buy_time']=='2019-11-08']['cust_id'].unique()
    # a是记录留存用户数, 初始为0个
    a = 0
    # 判断user_nday中哪些用户是2019-11-05的用户, 如果是说明是留存用户
    for i in user_nday:
        if i in new_user:
            a+=1
    a
    # 2019-11-05 一共有多少个新用户
    b = len(new_user)
    b 
    # 留存率
    a / b
    
    • 封装到函数中

      def cal_retention(data, n): # n为n日留存
          # 定义空列表, 存储老用户
          user=[]
          date=pd.Series(data.buy_time.unique()).sort_values()[:-n] #时间截取至最后一天的前n天,不截取的话最后的日期是无法计算n日留存率的
          retention_rates=[]
          # 循环遍历日期, 计算每天的留存率
          for i in date:
              new_user=set(data[data.buy_time==i].cust_id.unique())-set(user) #识别新用户,本案例中设初始用户量为零,当前天中如果出现了之前user中的用户,说明此用户是第二次购买不再是新用户,留存率统计的是新用户的,所以需要去掉
              user.extend(new_user)  #将新用户加入老用户群中
              #第n天留存情况
              user_nday=data[data.buy_time==i+timedelta(n)].cust_id.unique() #第n天登录的用户情况
              a=0
              #循环第n天登录的用户,和new_user中的用户对比,如果在new_user中,说明new_user中的用户在第n天又进行了登录,此时这个用户就是留存的用户,a值就加1
              for cust_id in user_nday:
                  if cust_id in new_user:
                      a+=1
              retention_rate=a/len(new_user) #计算该天第n日留存率
              retention_rates.append(retention_rate)
          # 创建s对象
          data_retention = pd.Series(retention_rates, index=date)
          return data_retention
      data_retention = cal_retention(data1, 3)
      data_retention
      
  • 计算每日购买人数和购买率

    # 每天购买人数和购买率
    # 购买人数 -> 发生购买行为的数据中的人数, 人数指定是一个人在一天中发生多次购买记录也记作一个人
    # 购买率 -> 购买人数 / 当天总数(包含pv,fav,cart,buy)
    
    # 每天购买人数
    # 对日期和客户id去重, 获取每天每个用户的购买数据子集
    day_buy_user_num = data1[data1['be_type']=='buy'].drop_duplicates(subset=['buy_time', 'cust_id']).groupby(by='buy_time')['cust_id'].count()
    day_buy_user_num
    
    # 每天购买率 = 每天购买人数 / 每天总人数
    # 每天总人数
    day_active_user_num = data1.drop_duplicates(subset=['buy_time', 'cust_id']).groupby(by='buy_time')['cust_id'].count()
    # 购买率
    day_buy_rate = day_buy_user_num / day_active_user_num
    day_buy_rate
    
    # 数据可视化
    plt.figure(figsize=(16,8))
    plt.plot(day_buy_user_num.index, day_buy_user_num.values)
    
    day_buy_rate.plot()
    
  • 复购率

    # 复购率=有复购行为的用户数/有购买行为的用户数
    # 复购: 一个用户多天进行购买,  一天有多次购买也记作一次购买
    # 统计每个用户购买次数(天数)
    df_rebuy = data1[data1['be_type']=='buy'].drop_duplicates(subset=['cust_id', 'buy_time']).groupby(by='cust_id')['buy_time'].count()
    df_rebuy.head()
    # 复购率, 购买次数大于等于2条目数/总的条目数
    df_rebuy[df_rebuy>=2].count() / df_rebuy.count()
    
  • 各阶段转换

    # 各个阶段转化率计算
    # 加购物车和收藏转化率 = 加购物车和收藏条目数 / 点击条目数
    # 购买转化率 = 购买条目数 / 点击条目数
    behavior_count
    # 获取加购车条目数
    cart_value = behavior_count['cart']
    # 获取收藏条目数
    fav_value = behavior_count['fav']
    # 计算加购车和收藏的条目数
    fav_cart_value = cart_value + fav_value
    # 获取点击条目数
    pv_value = behavior_count['pv']
    # 计算加购车和收藏转化率
    fav_cart_ratio = fav_cart_value / pv_value
    fav_cart_ratio
    # 计算购买转化率
    buy_value = behavior_count['buy']
    buy_ratio = buy_value / pv_value
    buy_ratio
    
    # 各个阶段条目数漏斗模型
    !pip install plotly
    attr = ['点击', '加入购物车', '收藏', '购买'] # 设置stage标签
    # 需要安装 plotly 包, pip install plotly
    import plotly.express as px # 绘图能看懂会用就好,不需要记
    data = dict(
        # x轴数据列表
        number=[pv_value, cart_value, fav_value, buy_value],
        # y轴数据列表
        stage=attr)
    data
    fig = px.funnel(data_frame=data, x='number', y='stage')
    fig.show()
    
  • 不同类别商品分析

    # 统计前十不同商品类别的购买条目数
    # 统计前十不同商品类别的点击条目数
    # 以上两者合并
    # 统计不同商品类别的点击,加购物车,收藏,购买条目数, 购买转化率
    
    # 统计前十不同商品类别的购买条目数
    product_buy_count = data1[data1['be_type']=='buy'][['cust_id', 'group_id']].groupby(by='group_id')[['cust_id']].count().rename(columns={'cust_id':'销售次数'})
    product_buy_count = product_buy_count.sort_values(by='销售次数', ascending=False).head(10)
    product_buy_count
    
    # 统计前十不同商品类别的点击条目数
    product_pv_count = data1[data1['be_type']=='pv'][['cust_id', 'group_id']].groupby(by='group_id')[['cust_id']].count().rename(columns={'cust_id':'点击次数'})
    product_pv_count = product_pv_count.sort_values(by='点击次数', ascending=False).head(10)
    product_pv_count
    
    # 以上两者合并 横向合并
    pd.concat([product_buy_count, product_pv_count], axis=1)
    
    # 统计不同商品类别的点击,加购物车,收藏,购买条目数, 购买转化率
    # 通过透视表操作
    item_behavior = pd.pivot_table(data=data1, index='group_id', columns='be_type', values='cust_id', aggfunc='count').fillna(0)
    # 计算每类商品的购买转化率, 新增一列
    item_behavior['购买转化率'] = item_behavior['buy'] / item_behavior['pv']
    item_behavior.sort_values(by='购买转化率', ascending=True)
    

    在这里插入图片描述

标签:buy,pv,cust,28,详解,rfm,data,id,RFM
From: https://blog.csdn.net/syhiiu/article/details/140217850

相关文章

  • 运维锅总详解CPU
    本文从CPU简介、衡量CPU性能指标、单核及多核CPU工作流程、如何平衡CPU性能和防止CPU过载、为什么计算密集型任务要选择高频率CPU、超线程技术、CPU历史演进及摩尔定律等方面对CPU进行详细分析。希望对您有所帮助!一、CPU简介CPU(中央处理器)的主要功能是执行计算机程序中......
  • 51单片机:多功能时钟(附代码详解)
    一、基本功能介绍:1.时钟系统(TIME-24h)1.可根据当地时间自由修改!(非联网)按下按键S1                          默认时间05:12:01(小彩蛋*1)           使用定时器完成,保证在执行其他功能时,这套时钟......
  • 详解前缀码与前缀编码
    前缀编码是一种数据压缩技术,也被称为可变长度编码。它的基本原理是将频繁出现的字符或字符序列用较短的编码表示,而较少出现的字符或字符序列用较长的编码表示,从而达到压缩数据的目的。概念定义前缀码:给定一个编码序列的集合,若不存在一个序列是另一个序列的前缀,则该序列......
  • Appium+python自动化(四十二)- 寿终正寝完结篇 - 结尾有惊喜,过时不候(超详解)
    1.简介 按照上一篇的计划,今天给小伙伴们分享执行测试用例,生成测试报告,以及自动化平台。今天这篇分享讲解完。Appium自动化测试框架就要告一段落了。2.执行测试用例&报告生成 测试报告,宏哥已经讲解了testng、HTMLTestRunner、allure等等,今天就在讲解一个新的测试报告BSTest......
  • ARMv8寄存器详解
    文章目录一、ARMv8寄存器介绍二、通用寄存器三、PSTAE寄存器四、特殊寄存器五、系统寄存器一、ARMv8寄存器介绍本文我来给大家介绍一下ARMv8的寄存器部分,ARMv8中有34个寄存器,包括31个通用寄存器、一个栈指针寄存器SP(X31),一个程序计数器寄存器PC,一个处理器状态寄存......
  • scanf,getchar,gets知识详解
    1.scanf  scanf用于输入数据,它处理不了空格键和回车键(enter),两者其实都是字符,键盘上每一个键位都是一个字符,空格对对应'\0',回车对应'\n'。,scanf将处理不了的这两种键放入缓冲区。缓冲区类似数据结构中的队列,一边只负责进,一边只负责出。顺序进出。(1)当数据为单个字符时:......
  • HTTP请求详解及其在嵌入式系统中的应用
    前言HTTP(HyperTextTransferProtocol,超文本传输协议)是互联网中最广泛使用的应用层协议,用于客户端和服务器之间的数据传输。了解HTTP请求的工作原理对于开发网络应用和嵌入式系统中的网络通信至关重要。本文将详细介绍HTTP请求的基本概念、类型、结构,并探讨其在嵌入式系统中的......
  • Docker-文件分层与数据卷挂载详解(附案例)
    文章目录文件分层数据卷挂载的含义数据卷挂载实践数据卷挂载案例数据卷挂载方式数据卷常用命令容器间数据共享更多相关内容可查看文件分层例:拉取mysql5.7的镜像,在继续拉取mysql5.8的镜像,会出现一部分文件已存在的现象这种分层技术是docker强大的功能点之一......
  • 2、flask-run启动参数详解
    app.py这里 app.run(True,port=5001,host='0.0.0.0')fromflaskimportFlask#创建flask应用对象app=Flask(__name__)@app.route('/')#路由defhello_world():#视图函数return'HelloWorld!'#响应给前端#添加路由和视图函数@app.route......
  • Python分支结构详解
    在编程中,控制流结构是至关重要的,它决定了程序的执行顺序。Python提供了多种控制流结构,其中分支结构是基础且常用的。本文将详细介绍Python中的分支结构,包括顺序结构、选择结构、单分支、双分支、多分支、分支嵌套以及pass关键字的使用。1.顺序结构、选择结构顺序结构是最简......