指标,具备业务含义,能够对业务进行量化的统计数据,有几个要点:
复购率和回购率
用户交易常用指标
商品管理常用指标
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模型是使用得较为广泛的客户关系管理分析模式。RFM模型是衡量客户价值和客户创利能力的重要工具和手段,通过一个客户的近期购买行为、购买的频率以及花钱的多少三项指标来描述该客户的价值状况。
在RFM模式中,R(Recency)表示客户最近一次购买的时间有多远,F(Frequency)表示客户在最近一段时间内购买的次数,M(Monetary)表示客户在最近一段时间内购买的金额。RFM模型强调以客户的行为来区分客户。利用RFM分析,我们可以做以下几件事情:
在使用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模型是所有产品经理都要了解的一个数据模型。
参考链接:https://zhuanlan.zhihu.com/p/32696403
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