python数据分析第9天
2021/12/17 22:23:32
本文主要是介绍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
这篇关于python数据分析第9天的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-05-08有遇到过吗?同样的规则 Excel 中 比Python 结果大
- 2024-03-30开始python成长之路
- 2024-03-29python optparse
- 2024-03-29python map 函数
- 2024-03-20invalid format specifier python
- 2024-03-18pool.map python
- 2024-03-18threads in python
- 2024-03-14python Ai 应用开发基础训练,字符串,字典,文件
- 2024-03-13id3 algorithm python
- 2024-03-13sum array elements python