python数据分析第9天

python数据分析第9天

电商网站用户/订单/活动数据分析项目

商业模式

  1. B2B:商家对商家(企业卖家对企业买家),交易双方都是企业,最典型的案例就是阿里巴巴,汇聚了各行业的供应商,特点是订单量一般较大。
  2. B2C:商家对个人(企业卖家对个人买家),例如:唯品会,聚美优品。
  3. B2B2C:商家对商家对个人,例如:天猫、京东。
  4. C2C:个人(卖家)对个人(买家),例如:淘宝、人人车。
  5. O2O:线上(售卖)到线下(提货),将线下的商务机会与互联网结合,让互联网成为线下交易的平台,让消费者在享受线上优惠价格的同时,又可享受线下贴心的服务,例如:美团、苏宁易购、大众点评。
  6. C2B:个人对商家(个人买家对企业卖家),先有消费者提出需求,后有商家按需求组织生产,例如:尚品宅配。
  7. 其他:ABC(代理-商家-消费者)、F2C(工厂-个人)、B2G(*采购)、BoB(供应商-运营者-采购商)、SoLoMo(社交-本地化-移动端)……。

核心指标

指标,具备业务含义,能够对业务进行量化的统计数据,有几个要点:

  1. 指标必须是数值,不能是文本、日期等。
  2. 指标都是汇总计算出来的,单个明细数据不是指标。
python数据分析第9天python数据分析第9天python数据分析第9天

指标详解

  1. 复购率和回购率

    • 复购率:复购(某段时间有2次及以上购买行为)用户的占比。复购率能反映用户的忠诚度,监测周期一般较长。
    • 回购率:回购率一般监测周期较短,可以反映如短期促销活动对用户的吸引力。
  2. 用户交易常用指标

    • 访问次数(PV):一定时间内某个页面的浏览次数。
    • 访问人数(UV):一定时间内访问某个页面的人数。
    • 加购数:将某款商品加入到购物车的用户数。
    • 收藏数:收藏某款商品的用户数。
    • GMV(总交易额、成交总额):Gross Merchandise Volume,通常称之为“交易流水”。
    • 客单价(ARPU):“$ 总收入 / 总用户数 $”,某些平台也用ARPPU表示客单价。
    • 转化率:“$ 付费用户数 / 访客数 $”。
    • 折扣率:“$ 销售额 / 吊牌总额 ” , 其 中 吊 牌 总 额 为 : “ ”,其中吊牌总额为:“ ”,其中吊牌总额为:“ 吊牌价 \times 销量 $”。
    • 拒退量:拒收和退货的总数量。
    • 拒退额:拒收和退货的总金额。
    • 实际销售额:“$ 销售额 - 拒退额 $”。
  3. 商品管理常用指标

    • SPU数:Standard Product Unit,商品的基本信息。
    • SKU数:Standard Keeping Unit,商品的库存信息。
    • 售卖比:“$ GMV / 备货值 $”,了解商品流转情况,可以用于库存优化。
    • 动销率:“$ 有销量的SKU数 / 在售SKU数 $”。
python数据分析第9天

代码实操

第一部分:订单数据分析

  1. 提取2019年的订单数据
  2. 处理业务流程不符的数据(支付时间早于下单时间、支付时长超过30分钟、订单金额小于0、支付金额小于0)
  3. 处理渠道为空的数据(补充众数)
  4. 处理平台类型字段(去掉多余的空格,保持数据一致)
  5. 添加折扣字段,处理折扣大于1的字段(将支付金额修改为“订单金额*平均折扣”)

  1. 交易总金额(GMV)、总销售额、实际销售额、退货率、客单价
  2. 每月GMV及趋势分析(折线图)
  3. 流量渠道来源拆解GMV占比(饼图)
  4. 周一到周日哪天的下单量最高、每天哪个时段下单量最高(柱状图)
  5. 用户复购率分析
import numpy as np
import pandas as pd

order_df = pd.read_excel('data/excel/某电商网站订单数据.xlsx', index_col='id')
order_df.info()

order_df.head()
order_df.shape

# 1. 提取2019年的订单数据
order_df.drop(index=order_df[order_df.orderTime.dt.year != 2019].index, inplace=True)
order_df.shape

# 1. 提取2019年的订单数据
order_df.drop(index=order_df[order_df.orderTime.dt.year != 2019].index, inplace=True)
order_df.shape

# 删除与业务流程不符的数据(支付时长超过30分钟)
delta = order_df.payTime - order_df.orderTime
order_df.drop(index=order_df[delta.dt.total_seconds() > 1800].index, inplace=True)
order_df.shape

# 删除与业务流程不符的数据(订单金额小于0、支付金额小于0)
order_df.drop(order_df[(order_df.payment < 0) | (order_df.orderAmount < 0)].index, inplace=True)
order_df.shape

# 修改有问题的列名
order_df.rename(columns={'chanelID': 'channelID', 'platfromType': 'platformType'}, inplace=True)
order_df.info()

# 3. 处理渠道为空的数据(补充众数)
channel_id = order_df.channelID.mode()[0]
# order_df.fillna(channel_id, inplace=True)
order_df['channelID'] = order_df.channelID.fillna(channel_id)
order_df.info()

# 4. 处理平台类型字段(去掉多余的空格,保持数据一致)
order_df['platformType'] = order_df.platformType.str.replace(r'\s', '', regex=True).str.title()
order_df.head()

# 5. 添加折扣字段,处理折扣大于1的字段(将支付金额修改为“订单金额*平均折扣”)
order_df['discount'] = np.round(order_df.payment / order_df.orderAmount, 2)
order_df

mean_discount = round(order_df[order_df.discount <= 1].discount.mean(), 2)
mean_discount

order_df['payment'] = order_df.payment.where(
    order_df.discount <= 1, np.round(order_df.orderAmount * mean_discount, 2)
)
order_df[order_df.discount > 1]


# 6. 交易总金额(GMV)、总销售额、实际销售额、退货率、客单价(ARPPU)
gmv = order_df.orderAmount.sum()
total_amount = order_df.payment.sum()
total_payment = order_df[order_df.chargeback == '否'].payment.sum()
back_rate = order_df[order_df.chargeback == '是'].orderID.count() / order_df.orderID.count()
arppu = total_payment / order_df.userID.nunique()
print(f'GMV: {gmv / 10000:.2f}万元')
print(f'总销售额: {total_amount / 10000:.2f}万元')
print(f'实际销售额: {total_payment / 10000:.2f}万元')
print(f'退货率: {round(back_rate * 100, 2)}%')
print(f'客单价: {round(arppu, 2)}元')

GMV: 10852.72万元
总销售额: 10263.48万元
实际销售额: 8894.43万元
退货率: 13.18%
客单价: 1130.87元

# 7. 每月GMV及趋势分析(折线图)
import pyecharts.options as opts
from pyecharts.charts import Line

order_df['month'] = order_df.orderTime.dt.month
gmv_by_month = np.round(order_df.groupby('month').orderAmount.sum() / 10000, 2)
payment_by_month = np.round(order_df[order_df.chargeback == '否'].groupby('month').payment.sum() / 10000, 2)

line = Line(init_opts=opts.InitOpts(width='800px', height='400px'))
line.set_global_opts(
    xaxis_opts=opts.AxisOpts(name='月份'),
    yaxis_opts=opts.AxisOpts(
        name="金额(万元)",
        min_=400,
        max_=1200,
        interval=200,
        splitline_opts=opts.SplitLineOpts(
            is_show=True, 
            linestyle_opts=opts.LineStyleOpts(opacity=0.5, type_='dotted')
        ),
    ),
)
line.add_xaxis([f'{i}月' for i in range(1, 13)])
line.add_yaxis(
    series_name='GMV',
    y_axis=gmv_by_month.values.tolist(),
    symbol="triangle",
    symbol_size=10
)
line.add_yaxis(
    series_name='实际销售额',
    y_axis=payment_by_month.values.tolist(),
    symbol="emptyCircle",
    symbol_size=10
)
line.render_notebook()

python数据分析第9天

# 8. 按渠道拆解GMV占比(饼图)
ser = np.round(order_df.groupby('channelID').orderAmount.sum() / 10000, 2)
ser.sort_values(ascending=False, inplace=True)
ser
from pyecharts.charts import Pie

pie = Pie(init_opts=opts.InitOpts(width='600px', height='450px'))
pie.add(
    '',
    [(index, ser[index]) for index in ser.index],
    radius=['40%', '70%'],
    center=['60%', '55%'],
    is_clockwise=False
)
pie.set_global_opts(
    title_opts=opts.TitleOpts(title="渠道GMV占比", pos_left='45%', pos_top='5%'),
    legend_opts=opts.LegendOpts(orient="vertical", pos_top="15%", pos_left="2%"),
)
pie.set_series_opts(label_opts=opts.LabelOpts(formatter="{d}%"))
pie.render_notebook()

python数据分析第9天

# 9. 周一到周日哪天的下单量最高、每天哪个时段下单量最高(柱状图)
from pyecharts.charts import Bar

order_df['weekday'] = (order_df.orderTime.dt.dayofweek + 1) % 7
temp = pd.pivot_table(order_df, index='weekday', values='orderID', aggfunc='nunique')
bar = Bar(init_opts=opts.InitOpts(width='640px', height='320px'))
bar.add_xaxis([f'星期{x}' for x in '日一二三四五六'])
bar.add_yaxis('订单量', temp['orderID'].values.tolist(), bar_width='50%')
bar.set_global_opts(
    legend_opts=opts.LegendOpts(is_show=False),
    yaxis_opts=opts.AxisOpts(name='订单量', name_gap=32),
    visualmap_opts=opts.VisualMapOpts(
        type_='color',
        range_text=('高', '低'),
        range_opacity=1,
        orient='vertical',
        pos_left='85%',
        pos_bottom='14%',
        min_=10000,
        max_=20000   
    )
)
bar.render_notebook()

python数据分析第9天

order_df['hour'] = order_df.orderTime.dt.floor('30T').apply(lambda x: f'{x.hour:0>2d}:{x.minute:0>2d}')
temp = pd.pivot_table(order_df, index='hour', values='orderID', aggfunc='nunique')
bar = Bar(init_opts=opts.InitOpts(width='1600px', height='400px'))
bar.add_xaxis(temp.index.values.tolist())
bar.add_yaxis(
    '订单量', temp['orderID'].values.tolist(), 
    bar_width='40%'
)
bar.set_global_opts(
    legend_opts=opts.LegendOpts(is_show=False)
)
bar.render_notebook()

python数据分析第9天

# 10. 用户复购率(有重复购买行为的用户数/有购买行为的用户数)分析
def handle_data(x):
    if x > 1:
        return 1
    elif x == 1:
        return 0
    return np.nan



# 根据用户和月两个维度统计不重复的订单数
temp_df = pd.pivot_table(
    order_df, 
    index='userID', columns='month',
    values='orderID',
    aggfunc='nunique'
)
# 对数据进行处理 - 有复购行为的记为1,有购买行为的记为0,没有购买行为保留空值
temp_df = temp_df.applymap(handle_data)
temp_df

# 以月为窗口统计复购率
temp_df.sum() / temp_df.count()

order_df['quarter'] = order_df.orderTime.dt.quarter
temp_df = pd.pivot_table(
    order_df, 
    index='userID', columns='quarter',
    values='orderID',
    aggfunc='nunique'
)
temp_df = temp_df.applymap(handle_data)
temp_df


# 以季度为窗口统计复购率
temp_df.sum() / temp_df.count()

第二部分:RFM模型和AARRR模型

  1. RFM模型

RFM模型是使用得较为广泛的客户关系管理分析模式。RFM模型是衡量客户价值和客户创利能力的重要工具和手段,通过一个客户的近期购买行为、购买的频率以及花钱的多少三项指标来描述该客户的价值状况。

在RFM模式中,R(Recency)表示客户最近一次购买的时间有多远,F(Frequency)表示客户在最近一段时间内购买的次数,M(Monetary)表示客户在最近一段时间内购买的金额。RFM模型强调以客户的行为来区分客户。利用RFM分析,我们可以做以下几件事情:

  1. 建立会员金字塔,区分各个级别的会员,如高级会员、中级会员、低级会员,然后针对不同级别的会员施行不同的营销策略,制定不同的营销活动。
  2. 发现流失及休眠会员,通过对流失及休眠会员的及时发现,采取营销活动,激活这些会员。
  3. 在短信、EDM(Email Direct Marketing)促销中,可以利用模型,选取最优会员。
  4. 维系老客户,提高会员的忠诚度。

在使用RFM模型时,可以给三个变量不同的权重或按一定的规则进行分组,然后组合三个变量,分出不同级别的会员。

order_df.drop(index=order_df[order_df.chargeback == '是'].index, inplace=True)
order_df.shape

# 获取RFM模型的原始数据
temp_df = pd.pivot_table(
    order_df, index='userID', 
    values=['orderTime', 'orderID', 'payment'],
    aggfunc={'orderTime': 'max', 'orderID': 'nunique', 'payment': 'sum'}
)
temp_df = temp_df.reindex(columns=['orderTime', 'orderID', 'payment'])
temp_df.rename(columns={'orderTime': 'R', 'orderID': 'F', 'payment': 'M'}, inplace=True)
temp_df

# 处理原始数据
from datetime import datetime

import seaborn as sns

last_day = datetime(2019, 12, 31, 23, 59, 59)
temp_df['R'] = (last_day - temp_df.R).dt.days
temp_df

def change_to_level(R):
    if R < 5:
        return 5
    elif R < 15:
        return 4
    elif R < 30:
        return 3
    elif R < 60:
        return 2
    return 1


temp_df['R'] = temp_df.R.apply(change_to_level)
temp_df

# 通过跟均值的比较给各项数据标记1或0
mean_value = temp_df.mean()
temp_df = temp_df.apply(lambda x: x - mean_value >= 0, axis=1)
temp_df

temp_df = temp_df.applymap(lambda x: '1' if x else '0')
temp_df

def make_tag(model):
    tags = {
        '111': '重要价值客户',
        '101': '重要发展客户',
        '011': '重要保持客户',
        '001': '重要挽留客户',
        '110': '一般价值客户',
        '100': '一般发展客户',
        '010': '一般保持客户',
        '000': '一般挽留客户'
    }
    key = model['R'] + model['F'] + model['M']
    return tags.get(key)


temp_df['Tag'] = temp_df.apply(make_tag, axis=1)
temp_df


ser = temp_df.groupby('Tag').Tag.count().astype(np.float64)
ser



from pyecharts.charts import Pie

pie = Pie(init_opts=opts.InitOpts(width='600px', height='600px'))
pie.add(
    '',
    [(index, ser[index]) for index in ser.index],
    radius=['35%', '60%'],
    center=['50%', '50%'],
)
pie.set_global_opts(
    legend_opts=opts.LegendOpts(is_show=False),
    # legend_opts=opts.LegendOpts(orient='vertical', pos_top="25%", pos_left="2%"),
)
pie.set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {d}%"))
pie.render_notebook()

python数据分析第9天

  1. AARRR模型

AARRR并不算是一种数据分析模型,而是一整套数据分析的思路和逻辑框架。AARRR模型是所有产品经理都要了解的一个数据模型。

python数据分析第9天

参考链接:https://zhuanlan.zhihu.com/p/32696403

第三部分:促销活动分析

  1. 活动期间(活动前、活动中、返场期)整体销售情况(订单数、付费人数、商品数、GMV、退单率、客单价)概览。
  2. 渠道获客质量分析(购买人数、购买商品数、GMV、订单数、总人数、转化率、ARPU、ARPPU)。
orders_df = pd.read_excel('data/excel/orderdata2021.xlsx')
orders_df


orders_df['day'] = orders_df.orderTime.dt.day
orders_df

def handle_day(x):
    if x <= 7:
        return '活动前'
    elif x <= 10:
        return '活动中' 
    return '活动后'


orders_df['activity'] = orders_df.day.apply(handle_day)
orders_df


#活动期间(活动前、活动中、返场期)整体销售情况(订单数、付费人数、商品数、GMV、退单率、客单价)概览。
#渠道获客质量分析(购买人数、购买商品数、GMV、订单数、总人数、转化率、ARPU、ARPPU)。

渠道获客质量分析(购买人数、购买商品数、GMV、订单数、总人数、转化率、ARPU、ARPPU)。
gmv_data = orders_df.pivot_table(
    index=['activity'],
    values=['orderID', 'userID', 'num', 'orderAmount', 'payment'],
    aggfunc={
        'orderID': 'nunique',
        'userID': 'nunique',
        'num': 'sum',
        'orderAmount': 'sum',
        'payment': 'sum'
    }
).reset_index()
gmv_data.rename(
    columns={
        'orderID': '订单数',
        'userID': '付费用户数',
        'num': '商品销量',
        'orderAmount': 'GMV',
        'payment': '付款金额'
    },
    inplace=True
)

total_payment_data = orders_df[orders_df.chargeback == '否'].pivot_table(
    index=['activity'],
    values=['orderID', 'userID', 'num', 'orderAmount', 'payment'],
    aggfunc={
        'orderID': 'nunique',
        'userID': 'nunique',
        'num': 'sum',
        'orderAmount': 'sum',
        'payment': 'sum'
    }
).reset_index()
total_payment_data.rename(
    columns={
        'orderID': '订单数(不含退款)',
        'userID': '付费用户数(不含退款)',
        'num': '商品销量(不含退款)',
        'orderAmount': 'GMV(不含退款)',
        'payment': '付款金额(不含退款)'
    },
    inplace=True
)

inall_data = gmv_data.merge(total_payment_data, on='activity')
inall_data['退单率'] = 1 - inall_data['订单数(不含退款)'] / inall_data['订单数']
inall_data['客单价'] = inall_data['GMV(不含退款)'] / inall_data['付费用户数(不含退款)']

inall_data = inall_data.reindex(index=[1, 0, 2])
inall_data


from datetime import datetime

start = datetime(2021, 1, 5)
end = datetime(2021, 1, 13, 23, 59, 59)

users_df = pd.read_excel('data/excel/users2021.xlsx')
users_df.drop(index=users_df[users_df.date < start].index, inplace=True)
users_df.drop(index=users_df[users_df.date > end].index, inplace=True)
users_df


users_df.rename(columns={'chanelID': 'channelID'}, inplace=True)
users_df

temp_df = orders_df.pivot_table(
    index='userID',
    values=['orderID', 'num', 'orderAmount', 'payment'],
    aggfunc={
        'orderID': 'nunique',
        'num': 'sum',
        'orderAmount': 'sum',
        'payment': 'sum'
    }
).reset_index()
temp_df['buy'] = 1
temp_df

buy_df = pd.merge(users_df, temp_df, how='left', on='userID')
buy_df.fillna(0, inplace=True)
buy_df



channel_ana_df = buy_df.pivot_table(
    index='channelID',
    values=['orderID', 'userID', 'buy', 'num', 'orderAmount', 'payment'],
    aggfunc={
        'orderID': 'sum',
        'userID': 'nunique',
        'buy': 'sum',
        'num': 'sum',
        'orderAmount': 'sum',
        'payment': 'sum'
    }
).reset_index()

channel_ana_df.rename(
    columns={
        'userID': '渠道来源总人数',
        'num': '购买商品数量',
        'buy': '购买人数',
        'orderAmount': 'GMV',
        'orderID': '下单数',
        'payment': '付款金额'
    }, 
    inplace=True
)

channel_ana_df['转化率'] = channel_ana_df['购买人数'] / channel_ana_df['渠道来源总人数']
channel_ana_df['ARPU'] = channel_ana_df['付款金额'] / channel_ana_df['渠道来源总人数']
channel_ana_df['ARPPU'] = channel_ana_df['付款金额'] / channel_ana_df['购买人数']
channel_ana_df

‘orderAmount’: ‘sum’,
‘payment’: ‘sum’
}
).reset_index()

channel_ana_df.rename(
columns={
‘userID’: ‘渠道来源总人数’,
‘num’: ‘购买商品数量’,
‘buy’: ‘购买人数’,
‘orderAmount’: ‘GMV’,
‘orderID’: ‘下单数’,
‘payment’: ‘付款金额’
},
inplace=True
)

channel_ana_df[‘转化率’] = channel_ana_df[‘购买人数’] / channel_ana_df[‘渠道来源总人数’]
channel_ana_df[‘ARPU’] = channel_ana_df[‘付款金额’] / channel_ana_df[‘渠道来源总人数’]
channel_ana_df[‘ARPPU’] = channel_ana_df[‘付款金额’] / channel_ana_df[‘购买人数’]
channel_ana_df


上一篇:Axios的正确食用方法


下一篇:使用python对excel表格商业数据可视化分析