2021-11-07大数据学习日志——Pandas——pandas综合案例(上)

案例1:零售会员数据分析

 

学习目标

  • 能够使用pandas、seaborn进行数据分析和可视化

1. 零售会员数据分析案例

1.1 案例业务介绍

案例背景

1)某女鞋连锁零售企业,当前业务以线下门店为主,线上销售为辅

2)通过对会员的注册数据以及消费数据的分析,监控会员运营情况,为后续会员运营提供决策依据

3)会员等级说明

  • 白银:注册(0)
  • 黄金:下单(1~3888)
  • 铂金: 3888~6888
  • 钻石:6888以上

分析需求

1)描述性数据分析

2)使用业务数据,分析出会员运营的基本情况

数据集说明

1)会员信息查询.xlsx

2)会员消费报表.xlsx

3)门店信息表.xlsx

4)全国销售订单数量表.xlsx

分析会员运营的基本情况

1)从量的角度分析会员运营情况

  • 整体会员运营情况(存量,月增量,不同等级占比)
  • 不同渠道(线上,线下)的会员运营情况
  • 线下业务,拆解到不同的地区、门店会员运营情况

2)从质的角度分析会员运营情况

  • 会销比
  • 连带率
  • 复购率

1.2 会员存量、增量分析

每月存量、增量是最基本的指标,通过会员数量考察会员运营情况

1)用到的数据:会员信息查询.xlsx,加载 会员信息查询.xlsx 数据

member_df = pd.read_excel('./data/会员信息查询.xlsx', engine='openpyxl')
member_df.info()

# 会员信息查询
member_df.head()

2)需要按月统计注册的会员数量,注册时间原始数据需要处理成年-月的形式

from datetime import datetime
member_df['注册年月'] = member_df['注册时间'].apply(lambda x: datetime.strftime(x, '%Y-%m'))
member_df.head()

3)按注册年月统计会员增量

分组聚合实现

month_count = member_df.groupby('注册年月')[['会员卡号']].count()
month_count.head()

# 修改列标签
month_count.columns = ['月增量']
month_count.head()

透视表实现

  • index:行索引,传入原始数据的列名
  • columns:列索引,传入原始数据的列名
  • values: 要做聚合操作的列名
  • aggfunc:聚合函数
month_count = member_df.pivot_table(index='注册年月', values='会员卡号', aggfunc='count')
month_count.head()

# 修改列标签
month_count.columns = ['月增量']
month_count.head()

4)在月增量数据的基础上统计月存量

# 通过 cumsum 对月增量做累积求和
month_count['存量'] = month_count['月增量'].cumsum()
month_count

5)从结果中剔除 2017-08 月份的数据

month_count = month_count[1:]
month_count.head()

6)对上面的统计结果进行可视化

%matplotlib inline
import matplotlib.pyplot as plt
# Mac 操作系统设置字体
# plt.rcParams['font.sans-serif'] = 'Arial Unicode MS'
# Win 操作系统设置字体
plt.rcParams['font.sans-serif'] = 'SimHei'

# 将月增量绘制折线图
month_count['月增量'].plot(figsize=(20, 8), color='r', secondary_y=True)
# 将存量绘制柱状图
month_count['存量'].plot.bar(color='gray', xlabel='年月', ylabel='存量', legend=True)

# 设置图形标题
plt.title('会员存量增量分析', fontsize=20)

1.3 增量等级分布

会员增量存量不能真实反映会员运营的质量,需要对会员的增量存量数据做进一步拆解

从哪些维度来拆解?

1)从指标构成来拆解

  • 会员 = 白银会员+黄金会员+铂金会员+钻石会员

2)从业务流程来拆解

  • 当前案例,业务分线上、线下,又可以进一步拆解:按大区,按门店

会员等级分布分析的目的和要分析的指标

1)会员按照等级拆解分为

  • 白银: 注册(0)
  • 黄金: 下单(1~3888)
  • 铂金: 3888~6888
  • 钻石: 6888以上

2)由于会员等级跟消费金额挂钩,所以会员等级分布分析可以说明会员的质量

具体实现

1)按照注册年月和会员等级,统计会员增量

分组聚合实现

month_degree_count = member_df.groupby(['注册年月', '会员等级'])['会员卡号'].count()
month_degree_count

# 进行 unstack 操作
month_degree_count.unstack()

透视表实现

month_degree_count = member_df.pivot_table(index='注册年月', 
                                           columns='会员等级', 
                                           values='会员卡号', 
                                           aggfunc='count')
month_degree_count

2)从结果中剔除 2017-08 月份的数据

month_degree_count = month_degree_count[1:]
month_degree_count.head()

3)对上面的统计结果进行可视化

# 将白银会员、黄金会员绘制柱状图
ax1 = month_degree_count[['白银会员', '黄金会员']].plot.bar(figsize=(20, 8), rot=0, 
                                                    xlabel='年月', ylabel='白银vs黄金', 
                                                    grid=True)
# 设置图例位置为:左上角
ax1.legend(loc='upper left')

# 拷贝一个和 ax1 共 x 轴的坐标系
ax2 = ax1.twinx()
# 将钻石会员、铂金会员绘制成折线图
month_degree_count[['铂金会员', '钻石会员']].plot(ax=ax2, color=['red', 'gray'], 
                                          ylabel='铂金vs钻石')
plt.title('会员增量等级分布')

1.4 增量等级占比分析

增量等级占比分析,查看增量会员的消费情况

1)计算每月新增会员总量

month_degree_count = month_degree_count.copy()
# axis=1:表示对每一行数据求和
month_degree_count['总计'] = month_degree_count.sum(axis=1)
month_degree_count.head()

2)计算白银和黄金会员等级占比,铂金钻石会员数量太少暂不计算

month_degree_count['白银会员占比'] = month_degree_count['白银会员']/month_degree_count['总计']
month_degree_count['黄金会员占比'] = month_degree_count['黄金会员']/month_degree_count['总计']
month_degree_count

3)对上面的统计结果进行可视化

# 将白银会员占比和黄金会员占比绘制折线图
month_degree_count[['白银会员占比', '黄金会员占比']].plot(figsize=(20, 8), color=['r', 'g'], 
                                              ylabel='占比', grid=True)

1.5 会员整体等级分布

计算各个等级会员占整体的百分比

思路:按照会员等级分组,计算每组的会员数量,用每组会员数量/全部会员数量

1)按照会员等级分组,计算每组的会员数量

分组聚合实现

ratio = member_df.groupby('会员等级')[['会员卡号']].count()
ratio

透视表实现

ratio = member_df.pivot_table(index='会员等级', values='会员卡号', aggfunc='count')
ratio

# 修改列标签
ratio.columns = ['会员数']
ratio

2)计算各个等级会员占比

ratio['占比'] = ratio['会员数']/ratio['会员数'].sum()
ratio

3)对上面的统计结果进行可视化

# 绘制饼图,查看不同等级会员占比
ratio.loc[['白银会员', '钻石会员', '黄金会员', '铂金会员'], '会员数'].plot.pie(figsize=(20, 8), 
                                                            autopct='%.1f%%')

1.6 线上线下增量分析

从业务角度,将会员数据拆分成线上和线下,比较每月线上线下会员的运营情况

1)按照注册年月和会员来源统计会员增量

分组聚合实现

from_data = member_df.groupby(['注册年月', '会员来源'])['会员卡号'].count()
from_data.head(6)

# unstack 操作
from_data = from_data.unstack()
from_data.head()

透视表实现

from_data = member_df.pivot_table(index='注册年月', 
                                  columns=['会员来源'], 
                                  values='会员卡号', 
                                  aggfunc='count')
from_data.head()

2)从结果中剔除 2017-08 月份的数据

from_data = from_data[1:]
from_data.head()

3)对上面的统计结果进行可视化

# 将不同来源的会员月增量绘制折线图
from_data.plot(figsize=(20, 8), grid=True)
plt.title('电商与线下会员增量分析', fontsize=20)

1.7 地区店均会员数量

思路:会员信息查询表中,只有店铺信息,没有地区信息,需要从门店信息表中关联地区信息

1)加载 门店信息表.XLSX 数据,并从中提取出 店铺代码 和 地区编码

store_info = pd.read_excel('./data/门店信息表.XLSX', engine='openpyxl')
store_info

store_info[['店铺代码', '地区编码']]

2)将会员信息数据和门店数据进行 merge 操作

country_info = pd.merge(member_df, store_info[['店铺代码', '地区编码']], 
                        left_on='所属店铺编码', right_on='店铺代码')
country_info.head()

3)统计不同地区的会员数量

注意只统计线下,不统计电商渠道, GBL6D01 地区为电商

# 统计不同地区的会员数量,剔除电商地区(GBL6D01)数据
country_info = country_info[country_info['地区编码']!='GBL6D01']
district = country_info.groupby('地区编码')[['会员卡号']].count()
district

4)修改列标签

# 修改列标签
district.columns = ['会员数量']
district.head()

 4)统计不同地区的店铺数

# 统计不同地区的店铺数
district['店铺数'] = country_info.groupby('地区编码')[['店铺代码']].nunique()
district

5)计算店均会员数和总平均会员数

district['每店平均会员数'] = round(district['会员数量']/district['店铺数'])
district['总平均会员数'] = district['会员数量'].sum()/district['店铺数'].sum()
district

6)按照店均会员数对数据进行排序

district = district.sort_values('每店平均会员数', ascending=False)
district

7)对上面的统计结果进行可视化

# 将每店平均会员数绘制柱状图
district['每店平均会员数'].plot.bar(figsize=(20, 8), color='r', legend=True, grid=True)
# 将总平均会员数绘制折线图
district['总平均会员数'].plot(figsize=(20, 8), color='g', legend=True, grid=True)
plt.title('地区店均会员分析', fontsize=18)

1.8 各地区会销比

会销比的计算和分析会销比的作用:

  • 会销比 = 会员消费的金额 / 全部客户消费的金额
  • 由于数据脱敏的原因,没有全部客户消费金额的数据,所以用如下方式替换
    • 会销比 = 会员消费的订单数 / 全部销售订单数
  • 会销比统计的是会员消费占所有销售金额的比例
  • 通过会销比可以衡量会员的整体质量

1)加载 全国销售订单数量表.xlsx 数据

all_orders = pd.read_excel('./data/全国销售订单数量表.xlsx', engine='openpyxl')
all_orders.head()

2)按照地区和年月统计会员订单数

member_orders = all_orders.pivot_table(values='会员订单数', 
                                       index='地区代码', 
                                       columns='年月', 
                                       aggfunc='sum', 
                                       margins='all')
member_orders

3)按照地区和年月统计全部订单数

country_sales = all_orders.pivot_table(values='全部订单数',
                                       index='地区代码', 
                                       columns='年月', 
                                       aggfunc='sum', 
                                       margins='all')
country_sales

4)计算会销比

result = member_orders / country_sales
result.applymap(lambda x: format(x, '.2%'))

1.9 各地区会员连带率分析

连带率的概念和为什么分析连带率:

1)连带率是指销售的件数和交易的次数相除后的数值,反映的是顾客平均单次消费的产品件数

2)为什么分析连带率?

  • 连带率直接影响到客单价
  • 连带率反应运营质量

3)分析连带率的作用

  • 通过连带率分析可以反映出人、货、场几个角度的业务问题

连带率的计算

  • 连带率 = 消费数量 / 订单数量

用到的数据

  • 会员消费报表.xlsx:会员消费记录
  • 门店信息表.xlsx:建立门店地区对应关系

案例分析实现

1)加载 会员消费报表 数据

member_consume = pd.read_excel('./data/会员消费报表.xlsx', engine='openpyxl')
member_consume

2)排除其中的 退单 数据

member_consume = member_consume.query('订单类型 == "下单"')
member_consume

3)给 member_consume 数据增加 年月 列

import numpy as np
member_consume['年月'] = pd.to_datetime(member_consume['订单日期']).apply(
    lambda x: datetime.strftime(x, '%Y%m')).astype(np.int32)
member_consume

3)将 member_consume(会员消费数据) 和 store_info(地区门店数据) 进行 merge 操作

ret = member_consume[['年月', '订单号', '店铺代码', '消费数量']].merge(
    store_info[['店铺代码', '地区编码']], on='店铺代码')
ret

4)剔除电商渠道的数据,电商渠道地区编码为:GBL6D01

ret = ret.query('地区编码!="GBL6D01"')
ret

5)按照地区和年月统计会员消费数量

consume_count = ret.pivot_table(index='地区编码', 
                                columns='年月', 
                                values='消费数量',
                                aggfunc='sum')
consume_count

6)按照地区和年月统计会员订单数

order_count = ret.pivot_table(index='地区编码', 
                              columns='年月', 
                              values='订单号',
                              aggfunc='nunique')
order_count

7)计算会员连带率

result = consume_count/order_count
result.applymap(lambda x: format(x, '.2f'))

1.10 会员复购率分析

复购率的概念和复购率分析的作用

  • 复购率:指会员对该品牌产品或者服务的重复购买次数,重复购买率越多,则反应出会员对品牌的忠诚度就越高,反之则越低。
  • 计算复购率需要指定时间范围
  • 如何计算复购:会员消费次数一天之内只计算一次
  • 复购率 = 一段时间内消费次数大于1次的人数 / 总消费人数
  • 复购率分析的作用:通过复购率分析可以反映出运营状态

复购率计算步骤

  • 统计会员消费次数与是否复购
  • 计算复购率并定义函数
  • 统计2018年01月~2018年12月复购率和2018年02月~2019年01月复购率
  • 计算复购率环比

案例分析实现

1)将 member_consume(会员消费数据) 和 store_info(地区门店数据) 进行 merge 操作

consume_data = member_consume[['年月', '订单日期', '卡号', '订单号', '订单类型', '店铺代码']]
order_data = consume_data.merge(
    store_info[['店铺代码', '地区编码']], on='店铺代码').query('订单类型!="退单"')
order_data

2)统计会员是否复购

由于一个会员同一天消费多次也算一次消费,所以会员消费次数按一天一次计算 因此需要对"会员卡号"和"时间"进行去重

order_data = order_data[['年月', '订单日期', '卡号', '地区编码']].drop_duplicates()
order_data

consume_count = order_data.groupby(['地区编码', '卡号']).size().reset_index()
consume_count

consume_count.rename(columns={0: '消费次数'}, inplace=True)
consume_count

# 判断是否复购
consume_count['是否复购'] = consume_count['消费次数'] > 1
consume_count

3)按地区统计消费人数和复购人数

# 统计消费人数和复购人数
depart_data = consume_count.pivot_table(index='地区编码', 
                                        values=['卡号', '是否复购'], 
                                        aggfunc={'卡号': 'count', '是否复购': 'sum'})
depart_data.columns = ['消费人数', '复购人数']
depart_data

4)计算复购率

depart_data['复购率'] = depart_data['复购人数']/depart_data['消费人数']
depart_data

5)定义计算指定时间范围复购率的函数

def stats_reorder(start, end, col):
    """统计指定起始年月的复购率"""
    # 会员下单消费数据和地区门店数据进行 merge
    consume_data = member_consume[['年月', '订单日期', '卡号', '订单号', '订单类型', '店铺代码']]
    order_data = consume_data.merge(
        store_info[['店铺代码', '地区编码']], on='店铺代码').query('订单类型!="退单"')
    # 筛选日期
    order_data= order_data[(order_data['年月']<=end) & (order_data['年月']>=start)]
    # 因为需要用到地区编号和年月  所以选择 年月、订单日期、卡号、地区编码 四个字段一起去重
    order_data=order_data[['年月', '订单日期', '卡号', '地区编码']].drop_duplicates()

    # 按照地区编码和卡号进行分组  统计订单日期数量  就是每个地区每个会员的购买次数
    consume_count = order_data.groupby(['地区编码', '卡号']).size().reset_index()
    # 重命名列
    consume_count.rename(columns={0:'消费次数'}, inplace=True)

    # 判断是否复购
    consume_count['是否复购']=consume_count['消费次数']>1
    # 统计每个地区的购买人数和复购人数
    depart_data=consume_count.pivot_table(index = ['地区编码'], 
                                          values=['卡号', '是否复购'], 
                                          aggfunc={'卡号':'count', '是否复购':'sum'})
    # 重命名列
    depart_data.columns=['复购人数', '购买人数']

    # 计算复购率
    depart_data[col+'复购率']=depart_data['复购人数']/depart_data['购买人数']

    return depart_data

6)统计2018年01月~2018年12月复购率和2018年02月~2019年01月复购率

reorder_2018 = stats_reorder(201801, 201812, '2018.01-2018.12')
reorder_2018

reorder_2019 = stats_reorder(201802, 201901, '2018.02-2019.01')
reorder_2019

7)计算2018年01月~2018年12月和2018年02月~2019年01月复购率环比

result = pd.concat([reorder_2018['2018.01-2018.12复购率'], reorder_2019['2018.02-2019.01复购率']], axis=1)
result

result['环比'] = result['2018.02-2019.01复购率'] - result['2018.01-2018.12复购率']
result

result = result.applymap(lambda x: format(x, '.2%'))
result

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值