python数据分析第9天
作者:互联网
python数据分析第9天
电商网站用户/订单/活动数据分析项目
商业模式
- B2B:商家对商家(企业卖家对企业买家),交易双方都是企业,最典型的案例就是阿里巴巴,汇聚了各行业的供应商,特点是订单量一般较大。
- B2C:商家对个人(企业卖家对个人买家),例如:唯品会,聚美优品。
- B2B2C:商家对商家对个人,例如:天猫、京东。
- C2C:个人(卖家)对个人(买家),例如:淘宝、人人车。
- O2O:线上(售卖)到线下(提货),将线下的商务机会与互联网结合,让互联网成为线下交易的平台,让消费者在享受线上优惠价格的同时,又可享受线下贴心的服务,例如:美团、苏宁易购、大众点评。
- C2B:个人对商家(个人买家对企业卖家),先有消费者提出需求,后有商家按需求组织生产,例如:尚品宅配。
- 其他:ABC(代理-商家-消费者)、F2C(工厂-个人)、B2G(政府采购)、BoB(供应商-运营者-采购商)、SoLoMo(社交-本地化-移动端)……。
核心指标
指标,具备业务含义,能够对业务进行量化的统计数据,有几个要点:
- 指标必须是数值,不能是文本、日期等。
- 指标都是汇总计算出来的,单个明细数据不是指标。
指标详解
-
复购率和回购率
- 复购率:复购(某段时间有2次及以上购买行为)用户的占比。复购率能反映用户的忠诚度,监测周期一般较长。
- 回购率:回购率一般监测周期较短,可以反映如短期促销活动对用户的吸引力。
-
用户交易常用指标
- 访问次数(PV):一定时间内某个页面的浏览次数。
- 访问人数(UV):一定时间内访问某个页面的人数。
- 加购数:将某款商品加入到购物车的用户数。
- 收藏数:收藏某款商品的用户数。
- GMV(总交易额、成交总额):Gross Merchandise Volume,通常称之为“交易流水”。
- 客单价(ARPU):“$ 总收入 / 总用户数 $”,某些平台也用ARPPU表示客单价。
- 转化率:“$ 付费用户数 / 访客数 $”。
- 折扣率:“$ 销售额 / 吊牌总额 ” , 其 中 吊 牌 总 额 为 : “ ”,其中吊牌总额为:“ ”,其中吊牌总额为:“ 吊牌价 \times 销量 $”。
- 拒退量:拒收和退货的总数量。
- 拒退额:拒收和退货的总金额。
- 实际销售额:“$ 销售额 - 拒退额 $”。
-
商品管理常用指标
- SPU数:Standard Product Unit,商品的基本信息。
- SKU数:Standard Keeping Unit,商品的库存信息。
- 售卖比:“$ GMV / 备货值 $”,了解商品流转情况,可以用于库存优化。
- 动销率:“$ 有销量的SKU数 / 在售SKU数 $”。
代码实操
第一部分:订单数据分析
- 提取2019年的订单数据
- 处理业务流程不符的数据(支付时间早于下单时间、支付时长超过30分钟、订单金额小于0、支付金额小于0)
- 处理渠道为空的数据(补充众数)
- 处理平台类型字段(去掉多余的空格,保持数据一致)
- 添加折扣字段,处理折扣大于1的字段(将支付金额修改为“订单金额*平均折扣”)
- 交易总金额(GMV)、总销售额、实际销售额、退货率、客单价
- 每月GMV及趋势分析(折线图)
- 流量渠道来源拆解GMV占比(饼图)
- 周一到周日哪天的下单量最高、每天哪个时段下单量最高(柱状图)
- 用户复购率分析
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()
# 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()
# 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()
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()
# 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模型
- RFM模型
RFM模型是使用得较为广泛的客户关系管理分析模式。RFM模型是衡量客户价值和客户创利能力的重要工具和手段,通过一个客户的近期购买行为、购买的频率以及花钱的多少三项指标来描述该客户的价值状况。
在RFM模式中,R(Recency)表示客户最近一次购买的时间有多远,F(Frequency)表示客户在最近一段时间内购买的次数,M(Monetary)表示客户在最近一段时间内购买的金额。RFM模型强调以客户的行为来区分客户。利用RFM分析,我们可以做以下几件事情:
- 建立会员金字塔,区分各个级别的会员,如高级会员、中级会员、低级会员,然后针对不同级别的会员施行不同的营销策略,制定不同的营销活动。
- 发现流失及休眠会员,通过对流失及休眠会员的及时发现,采取营销活动,激活这些会员。
- 在短信、EDM(Email Direct Marketing)促销中,可以利用模型,选取最优会员。
- 维系老客户,提高会员的忠诚度。
在使用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()
- AARRR模型
AARRR并不算是一种数据分析模型,而是一整套数据分析的思路和逻辑框架。AARRR模型是所有产品经理都要了解的一个数据模型。
参考链接:https://zhuanlan.zhihu.com/p/32696403
第三部分:促销活动分析
- 活动期间(活动前、活动中、返场期)整体销售情况(订单数、付费人数、商品数、GMV、退单率、客单价)概览。
- 渠道获客质量分析(购买人数、购买商品数、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
标签:数据分析,index,temp,python,payment,df,order,opts 来源: https://blog.csdn.net/weixin_60148315/article/details/122004257