目的:
1 查看交易状况,分析销量下降的原因,交易额分解,顾客来源分析
2 顾客购买行为:复购、回购、留存分析、消费者生命周期、顾客消费能力差异
3 订单特征:下单时间、地区特征、价格特征
4 顾客分类
import pandas as pd
import numpy as np
from pyecharts.globals import CurrentConfig, OnlineHostType
CurrentConfig.ONLINE_HOST = OnlineHostType.NOTEBOOK_HOST
一 数据查看
d = pd.read_excel('数据.xlsx')
d.head()
d.info()
# 没有空值,数据类型正确
d.describe()
# 大部分 没有邮费,购买数量平均为1.5个,标准差1.48,大部分是1-2个;平均金额126,中位数115,右偏
# 订单特点是:小额订单较多,订单数量多为1-2件,邮费大部分为0
添加月份列和星期列
d = d.set_index('付款日期')
d['month'] = d.index.to_period('M')
d['付款日期'] = d.index
d['week'] = d.index.weekday
print('共 %s 周' % d.index.isocalendar().week.max())
共 26 周
二 销售波动分析
交易额波动原因分析:
购买周期为70天,交易额变化与之不符,交易额与订单量的变化最为一致,分析影响订单量的原因。将顾客分为新老客户、新顾客/活跃/不活跃/回流,发现新顾客、不活跃占比高,因此可断定用户流失情况严重。
交易成功订单
data = d[d['订单状态'] == '交易成功']
print('交易成功的订单数量为:',len(data))
print('\n统计日期从%s到%s' %(data['付款日期'].min(), data['付款日期'].max()),
'\n消费者数量:',data['买家昵称'].nunique(),
'\n总销售额:', data['实付金额'].sum(),
'\n总销售量:', data['购买数量'].sum(),
'\n总订单量:', len(data),
'\n单笔订单平均销售额:', round(data['实付金额'].mean(), 2),
'\n单笔订单平均购买件数:', round(data['购买数量'].mean(),2),
'\n客单价:', round(data['实付金额'].sum()/data['买家昵称'].nunique(),2),
'\n人均消费件数:', round(data['购买数量'].sum()/data['买家昵称'].nunique(),2)
)
销售额变化趋势:1-4月连续下滑,4-6月缓慢上升
销售额 = 订单量 x 客单价 x 连带率
1 是否与购买周期有关(不符)
t12 = data.groupby('买家昵称')['付款日期'].agg(['min','max'])
t12['life'] = (t12['max'] - t12['min']).dt.days
print('用户的平均购买周期为%s天'%round(t12['life'].mean(),2))
# 排除新客,统计消费两次及以上的
t12 = t12[t12['life']>0]
print('两次及以上购买的客户的平均购买周期为%s天' % round(t12['life'].mean(),2))
t12_ = t12['life'].value_counts().sort_index()
t12_[:5]
用户的平均购买周期为4.86天
两次及以上购买的客户的平均购买周期为71.31天
1 41
2 41
3 34
4 37
5 34
l = Line(init_opts=opts.InitOpts(height='350px', width='850px'))
l.add_xaxis([str(i) for i in t12_.index.tolist()])
l.add_yaxis('', t12_.tolist(),is_smooth=True,symbol='pin',symbol_size=10)
l.set_global_opts(
title_opts=opts.TitleOpts(title='用户购买周期分布'),
xaxis_opts=opts.AxisOpts(name='天数',boundary_gap=False),
yaxis_opts=opts.AxisOpts(name='频率'),
tooltip_opts=opts.TooltipOpts(trigger='axis')
)
l.render_notebook()
print('异常值右边界为:',t12.mean()+3*t12.std())
异常值右边界为: 40.81493910221057
t12[t12['life']==60]['min'].dt.date.value_counts()
2019-02-17 46
2019-02-19 14
2019-02-18 3
2019-03-20 1
2019-02-03 1
2019-02-20 1
2019-02-16 1
2019-02-09 1
2019-04-29 1
2019-03-27 1
Name: min, dtype: int64
t12[t12['life']==60]['max'].dt.date.value_counts()
2019-04-18 46
2019-04-20 14
2019-04-19 3
2019-04-21 2
2019-05-19 1
2019-05-27 1
2019-04-04 1
2019-06-28 1
2019-04-10 1
Name: max, dtype: int64
2 是否与订单量、客单价、连带率有关(与订单量有关)
t1 = data.groupby('month')[['实付金额','购买数量']].agg(['sum','mean'])
t1
from pyecharts.charts import Line
from pyecharts import options as opts
line = Line(init_opts=opts.InitOpts(height='350px', width='850px'))
line.add_xaxis(t1.index.strftime('%Y-%m').tolist())
line.add_yaxis('销售额', (t1['实付金额']['sum']/10000).tolist(), yaxis_index=0)
line.add_yaxis('销量', (t1['购买数量']['sum']/10000).tolist(), yaxis_index=1)
line.add_yaxis('订单量', data.groupby('month')['month'].count().tolist(), yaxis_index=2)
line.extend_axis(yaxis=opts.AxisOpts(type_='value', name='销量\n(万)', position='left', offset=50))
line.extend_axis(yaxis=opts.AxisOpts(type_='value', name='订单量', position='right'))
line.set_global_opts(
title_opts=opts.TitleOpts(title='各月总销售额、总销售量、订单量', pos_left=250),
xaxis_opts=opts.AxisOpts(boundary_gap=False, axistick_opts=opts.AxisTickOpts(is_align_with_label=True)),
yaxis_opts=opts.AxisOpts(name='总销售额\n(万)'),
tooltip_opts=opts.TooltipOpts(trigger='axis'),
legend_opts=opts.LegendOpts(orient='vertical', pos_right=150)
)
line.set_series_opts(label_opts=opts.LabelOpts(is_show=False))
line.render_notebook()
cust_month = data.groupby('month')['买家昵称'].apply(lambda x: x.nunique())
line = Line(init_opts=opts.InitOpts(height='350px', width='850px'))
line.add_xaxis(t1.index.strftime('%Y-%m').tolist())
line.add_yaxis('每单平均销售额', round(t1['实付金额']['mean'],0).tolist(), yaxis_index=0, symbol='pin',symbol_size=20)
line.add_yaxis('每单平均销量', round(t1['购买数量']['mean'],1).tolist(), yaxis_index=1, symbol='pin',symbol_size=20)
line.add_yaxis('客单价', round(t1['实付金额']['sum']/cust_month,2), yaxis_index=2)
line.add_yaxis('连带率', round(t1['购买数量']['sum']/cust_month,2), yaxis_index=3)
line.extend_axis(yaxis=opts.AxisOpts(type_='value', name='平均\n购买量', position='left', offset=50, max_=1.6, min_=1.4))
line.extend_axis(yaxis=opts.AxisOpts(type_='value', name='客单价', position='right', min_=100))
line.extend_axis(yaxis=opts.AxisOpts(type_='value', name='连带率', position='right', offset=50, min_=1))
line.set_global_opts(
title_opts=opts.TitleOpts(title='各月平均销售额、销售量、客单价、连带率', pos_left=200),
xaxis_opts=opts.AxisOpts(boundary_gap=False, axistick_opts=opts.AxisTickOpts(is_align_with_label=True)),
yaxis_opts=opts.AxisOpts(name='平均\n销售额', min_=100),
tooltip_opts=opts.TooltipOpts(trigger='axis'),
legend_opts=opts.LegendOpts(orient='vertical', pos_right=100)
)
line.set_series_opts(label_opts=opts.LabelOpts(is_show=False))
line.render_notebook()
与销售额变动最为一致的是订单量,客单价和连带率虽有变化,但波动范围较小,下面继续拆分销售额
3 销售额拆解(新老客差别在订单数)
销售额,按新老顾客分类,计算顾客数、客单价、件单价和连带率,件单价*连带率=客单价
t7 = data.pivot_table(index='买家昵称',columns='month',values='购买数量',aggfunc='count')
t7 = t7.applymap(lambda x: 1 if x>0 else 0) # 各月消费过的客户记为1
data['顾客类别'] = 0
# 标记新顾客和老顾客
users = []
for m in t7.columns:
curr_users = t7.index[t7[m]==1] # 本月购买者
new_users = curr_users[[u not in users for u in curr_users]] # 本月购买的没在之前的购买者中
users.extend(new_users)
data['顾客类别'