自学内容网 自学内容网

同期数分析-留存率

目录

同期数分析

加载数据

单月实现

统计每个月的订单量

求2月份的订单量和用户数量

求2月之前的历史订单量

筛选出2023年2月的新增的用户数

计算2023年2月在后面的留存情况

完整的2023年2月份同期群结果

遍历合并和分析

引入月份列表

遍历

调整成留存率的形式

回购客单的同期群实现

留存客单


同期数分析

同期群分析是数据分析中的经典思维,其核心逻辑是将用户按初始行为的发生时间划分为不同的群组,进而分析相似群组的行为如何随时间变化

举例:下表记录了每个月新购买的用户数,并统计每个月的新增用户在之后月份的复购情况

数据截止到2023年7月,如图下所示。

  • 数据的第一行,2023年1月有97个新用户

  • 之后的+1月(2023年2月)有46%的用户再次光顾

  • +2月(2023年3月)仍有39%的回头客

  • 第一行的46%、39%都是对应复购人数占2023年1月新增购买用户的比重,这些人属于2023年1月同一期的新增用户

  • 其他行也是一样的道理,每一行为同一个群组,反映同一期新增用户在之后一段时间复购行为的变化趋势。

上表的百分比为留存率,留存率=某月复购用户数/对应期新增用户数

我们也可以将留存率或者说是回购率中的回购,当做观察和分析的"行为",而如果把"回购客单价"当做追踪分析的行为,就可以从客单价的维度对用户进行分析.

前面的同期群分析是从时间的维度来划分群组的,也可以改变分组逻辑,用渠道+月份来划分群组.

加载数据

# 加载数据
import pandas as pd
df = pd.read_excel('../data/k_group_anlysis.xlsx')
df

单月实现

统计每个月的订单量

# 目标1: 统计每个月的订单量
# 1.1 加入 y_m 月份标签
df['y_m'] = df['付款时间'].astype(str).str[:7]
df['y_m'].unique()
# 1.2 统计每个月的订单量 且 排序
df['y_m'].value_counts().sort_index()

求2月份的订单量和用户数量

# 3.1 指定月份 '2023-02'
month = '2023-02'

# 3.2 筛选出指定月份相关的订单(订单数量)
sample = df[df['y_m'] == month]
print("二月份的订单量: ", len(sample))

# 3.3 求 指定月份 每个用户的总实付总额(用户数量)
sample_c = sample.groupby('用户ID')['实付金额'].sum().reset_index()
print("二月份的用户量: ", len(sample_c))

# 3.4 打印 3.3的前5条数据
sample_c.head()

求2月之前的历史订单量

history = df[df['y_m'] == '2023-01']
history.head()
print(history['y_m'].unique())

history = df.loc[df['y_m'] == '2023-01',:]
history.head()

筛选出2023年2月的新增的用户数

# 目标5: 筛选出2023年2月新增的用户数
sample_new = sample_c.loc[sample_c['用户ID'].isin(history['用户ID'])==False, :]

print('2月份新增用户数: ', len(sample_new))
sample_new.head()

sample_new = sample_c.loc[sample_c['用户ID'].isin(history['用户ID'])==False, :]

历史订单量是2023年1月,通过使用isin函数筛选出不是在1月订单量中就是2月新增的订单量.

计算2023年2月在后面的留存情况

# 目标6: 计算2023年2月在后面的留存情况
# 1 准备容器
re = []

# 2 遍历 ['2023-03', '2023-04', '2023-05', '2023-06','2023-07','2023-08','2023-09','2023-10','2023-11','2023-12']
for month in ['2023-03', '2023-04', '2023-05', '2023-06','2023-07','2023-08','2023-09','2023-10','2023-11','2023-12']:
    # print(month)
    # 2.1 获取下个月的数据
    next_month = df.loc[df['y_m'] == month, :]
    # print('---------------------')
    # print(next_month)
    
    # 2.2 获取留存的数据
    target_user = sample_new.loc[sample_new['用户ID'].isin(next_month['用户ID']), :]

    # 2.3 向容器中追加 yyyy-mm留存情况: 999
    re.append(f"{month} 留存情况: {len(target_user)}")
    
# 3 验证 
re

完整的2023年2月份同期群结果

# 加入新增数据,得到完整2023年2月份同期群结果
re.insert(0,['2023年2月新增用户:',len(sample_c)])
re

遍历合并和分析

引入月份列表

# 目标1 为了便于循环,我们引入了月份列表
month_lst = df['y_m'].unique()
print(month_lst)

遍历

# 1 月份列表 month_lst
month_lst = df['y_m'].unique()

# 2 准备最终容器 final
final = pd.DataFrame()

# 3 遍历月份列表
for i in range(len(month_lst)):
    # print(i, month_lst[i])
    # 3.1 构造和月份一样长的列表,方便后续格式统一 count
    count = [0] * len(month_lst)
    # print(count)

    # 3.2 筛选出当月订单,并按用户ID分组 target_month
    target_month = df[df['y_m'] == month_lst[i]]
    # print('---------------------------')
    # print(target_month)
    
    # 3.3 求当月订单每个用户的实付金额 target_users
    target_users = target_month.groupby("用户ID")['实付金额'].sum().reset_index()
    # print('---------------------------')
    # print(month_lst[i], len(target_users))
    
    # 3.4 判断是否是第一个月
    if i == 0:
        # 3.4.1 如果是第一个月,则跳过(因为不需要和历史数据验证是否为新增用户) new_target_users
        new_target_users = target_month.groupby("用户ID")['实付金额'].sum().reset_index()
    else:
        # 3.4.2 如果不是第一个月
        # 3.4.2.1 找到之前的历史订单 history
        history = df.loc[df['y_m'].isin(month_lst[:i])]
        # print(history)
        # print('-------------------------')
        
        # 3.4.2.2 筛选出未在历史订单中出现过的新增用户 new_target_users
        new_target_users = target_users.loc[target_users['用户ID'].isin(history["用户ID"])==False,:]
    
    # 3.5 将当月新增用户数放在第一个值中
    count[0] = len(new_target_users)
    # print(count)
    
    # 3.6 以月为单位,循环遍历,计算留存情况
    """
        for j, ct in zip(range(i+1,len(month_lst)), range(1, len(month_lst))):
            i = 2
                i+1=3, 12, [3, 4, 5, 6, 7, 8, 9, 10, 11]    
                1, 12, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
            i = 3
                i+=4, 12, [4, 5, 6, 7, 8, 9, 10, 11]
                1, 12, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
    """
    for j, ct in zip(range(i+1,len(month_lst)), range(1, len(month_lst))):
        # 3.6.1 下一个月的订单 next_month
        next_month = df.loc[df['y_m'] == month_lst[j], :]
        next_users = next_month.groupby("用户ID")['实付金额'].sum().reset_index()
        
        # 3.6.2 计算在该月仍然留存的用户数量
        isin = new_target_users['用户ID'].isin(next_users['用户ID']).sum()
        count[ct] = isin
        
    # print(count)
    
    # 3.7 格式转置
    result = pd.DataFrame({month_lst[i] : count}).T
    # print(result)
    # print('-------------------------------')
    
    # 3.8 合并
    final = pd.concat([final, result], axis=0)
    
# 4 指定列名 '当月新增','+1月','+2月','+3月','+4月','+5月','+6月','+7月','+8月','+9月','+10月','+11月'
final.columns = ['当月新增','+1月','+2月','+3月','+4月','+5月','+6月','+7月','+8月','+9月','+10月','+11月']

# 5 验证
final

调整成留存率的形式

# 目标: 调整成留存率的形式
# 1 让final每个元素 除以 当月新增, 只保留 第二列往后的列内容
result = final.divide(final['当月新增'], axis = 0).iloc[:,1:]
# 2 新增当月新增列
result['当月新增'] = final['当月新增']
# 3 验证
result

回购客单的同期群实现

#引入y_m
month_lst = df['y_m'].unique()

#后面加了个m,代表金额相关
final_m = pd.DataFrame()

#中间代码相同
for i in range(len(month_lst) - 1):
    
    #构造和月份一样长的列表,方便后续格式统一
    count = [0] * len(month_lst)
    
    #筛选出当月订单,并按用户昵称分组
    target_month = df.loc[df['y_m'] == month_lst[i],:]
    target_users = target_month.groupby('用户ID')['实付金额'].sum().reset_index()
    
    #如果是第一个月,则跳过(因为不需要和历史数据验证是否为新增用户)
    if i == 0:
        new_target_users = target_month.groupby('用户ID')['实付金额'].sum().reset_index()
    else:
        #如果不是,找到之前的历史订单
        history = df.loc[df['y_m'].isin(month_lst[:i]),:]
        #筛选出未在历史订单中出现过的新增用户
        new_target_users = target_users.loc[target_users['用户ID'].isin(history['用户ID']) == False,:]
    
    #将当月新增用户数放在第一个值中
    count[0] = len(new_target_users)
    
    #以月为单位,循环遍历,计算留存情况
    for j,ct in zip(range(i + 1,len(month_lst)),range(1,len(month_lst))):
        #下一个月的订单
        next_month = df.loc[df['y_m'] == month_lst[j],:]
        next_users = next_month.groupby('用户ID')['实付金额'].sum().reset_index()

        
        #计算在该月仍然留存的用户的回购金额
        isin_m = next_users.loc[next_users['用户ID'].isin(new_target_users['用户ID']) == True,'实付金额'].sum()
        count[ct] = isin_m
        
    #格式转置
    result = pd.DataFrame({month_lst[i]:count}).T
    
    #合并
    final_m = pd.concat([final_m,result])

final_m.columns = ['当月新增','+1月','+2月','+3月','+4月','+5月','+6月','+7月','+8月','+9月','+10月','+11月']

final_m

留存客单

# 留存客单
result_m = final_m / final
result_m['当月新增'] = final_m['当月新增']
result_m


原文地址:https://blog.csdn.net/weixin_58305115/article/details/142574779

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!