电商销售数据分析
1.背景与目标
2.数据准备
3.数据清洗
4.具体目标分析
5.案例结论
1.背景与目标
对一家全球超市4年(2011年-2014年)的零售数据进行数据分析
数据分析的目标:
* 分析每年销售额增长率
* 各个地区分店的销售额
* 销售淡旺季
* 新老客户数
* 利用RFM模型标记用户价值
2.数据准备
数据来源于数据科学竞赛平台,总共51290条数据,24个字段。
导入数据
import pandas as pd data= pd.read_csv('./dataset2011-2015.csv',encoding='ISO-8859-1') print('源数据的形状为:',data.shape) # print(data.head()) # data.head() data.info()
画图时兼容中文字体
import pandas as pd import numpy as np import matplotlib as plt import matplotlib as mpl # 设置字体 #rcParams 修改mat 配置文件 #了解 mpl.rcParams['font.sans-serif'] = ['SimHei']
# 导入数据,并将列名中文化 ''' csv常见编码格式:UTF-8、GBK 、ISO-8859-1 ''' #ISO-8859-1 编码格式 utf-8 gbk df = pd.read_csv('./dataset2011-2015.csv',encoding='ISO-8859-1') name_dict = { 'Row ID':'行编号', 'Order ID':'订单ID', 'Order Date':'订单日期', 'Ship Date':'发货日期', 'Ship Mode':'发货模式', 'Customer ID':'客户ID', 'Customer Name':'客户姓名', 'Segment':'客户类别', 'City':'客户所在城市', 'State':'客户城市所在州', 'Country':'客户所在国家', 'Postal Code':'邮编', 'Market':'商店所属区域', 'Region':'商店所属洲', 'Product ID':'产品ID', 'Category':'产品类别', 'Sub-Category':'产品子类别', 'Product Name':'产品名称', 'Sales':'销售额', 'Quantity':'销售量', 'Discount':'折扣', 'Profit':'利润', 'Shipping Cost':'发货成本', 'Order Priority':'订单优先级'} # df.rename(columns=name_dict,inplace=True) # df
3.数据清洗
这份数据主要训练的是数据分析方法,数据本身较为干净。即便如此,也要说一下数据清洗的要点:
数据处理(怎么发现?怎么做?)
-
缺失值:表名.isnull().sum() #对每个字段的缺失值进行加总
-
异常值:表名.describe() #对数值型的数据作基本描述
-
重复值:
表名.字段名.unique().size #104530
表名.字段名.size#104557 ,说明有重复值
表名.drop(表名[表名.字段名.duplicated()].index, inplace=True) -
错误值:类似于Excel中的筛选功能,字段中的属性有没有错误的情况。方法:表名.字段名.unique() #不重复的具体是哪几个
-
遇到日期格式的字段(订单日期)改为datetime,可以快速增加数据的维度,如:年,月,季度等(怎么取数)
#将字符串的日期格式转换成时间 df['Order Date'] = pd.to_datetime(df['Order Date']) df['Order Date'] # print(df.dtypes) # #拆分成年月 季度 # #每一列就是每一个维度,时间细分 df['Order-year'] = df['Order Date'].dt.year df['Order-month'] = df['Order Date'].dt.month df['quarter'] = df['Order Date'].dt.to_period('Q') df
4.具体目标分析
4.1.分析每年销售额的增长率
销售增长额是衡量企业经营状况和市场占有能力、预测企业经营业务拓展趋势的重要指标,也是企业扩张增量资本和存量资本的重要前提
销售额增长率=(本年销售额-上年销售额)/上销售额 * 100%
#分组 :计算每一年的销售总额 sales_year = df.groupby(by='Order-year')['Sales'].sum() sales_year #我们根据销售额增长率公式分别算出2012年、2013年和2014年的销售额增长率 #减1是因为增长点 sales_rate_11 = 0 # #我们将计算公式改型为(本年销售额/上销售额 – 1),计算与原表达式一致。 sales_rate_12=sales_year[2012]/sales_year[2011]-1 sales_rate_13=sales_year[2013]/sales_year[2012]-1 sales_rate_14=sales_year[2014]/sales_year[2013]-1 # # #如果想用百分数的形式结果,我们可以用下面的方式将小数改成百分数 sales_rate_12 = "%.2f%%" % (sales_rate_12 * 100) sales_rate_13 = "%.2f%%" % (sales_rate_13 * 100) sales_rate_14 = "%.2f%%" % (sales_rate_14 * 100) print(sales_rate_12) print(sales_rate_13) print(sales_rate_14)
sales_rate = pd.DataFrame( {'sales_all':sales_year, 'sales_rate':['0.00%',sales_rate_12,sales_rate_13,sales_rate_14] }) print(sales_rate)
进行可视化处理:
【需要说明的是,matplotlib画图效率太低,可以将处理好的数据用Excel快速出图】
结合上面的图表可以发现,2011年-2014年该超市的销售额在稳步上升,说明企业市场占有能力在不断提高,增长率2012年-2014年在增长后趋于平稳,说明企业经营在逐步稳定。
4.2.各个地区分店的销售额
sales_area = data.groupby(by='Market')['Sales'].sum() sales_area.plot(kind='pie',autopct="%1.1f%%",title='2011年-2014年的总销售额占比')
sales_area = data.groupby(by=['Market','Order-year'])['Sales'].sum() # 将分组后的多层索引设置成列数据 sales_area = sales_area.reset_index(level=[0,1]) # 使用数据透视表重新整理数据 sales_area = pd.pivot_table(sales_area, index='Market', columns='Order-year', values='Sales') # 绘制图形 sales_area.plot(kind = 'bar',title = '2011年-2014年不同地区销售额对比')
category_sales_area = data.groupby(by=['Market','Category'])['Sales'].sum() category_sales_area # 将分组后的多层索引设置成列数据 category_sales_area = category_sales_area.reset_index(level=[0,1]) # 使用数据透视表重新整理数据 category_sales_area = pd.pivot_table(category_sales_area, index='Market', columns='Category', values='Sales') # 绘制图形 category_sales_area.plot(kind = 'bar', title = '不同类型产品在不同地区销售额对比', figsize= (10,8) )
4.3.销售淡旺季分析
了解了该超市了的整体销售额情况和不同类型产品在不同地区的销售情况之后,我们再对每年每月的销售额进行分析,根据不同月份的销售情况,找出重点销售月份,从而制定制定经营策略与业绩月度及季度指标拆分。
#销售淡旺季分析 #10.4.3 销售淡旺季分析 # 了解了该超市了的整体销售额情况和不同类型产品在不同地区的销售情况之后,我们再对每年每月的销售额进行分析,根据不同月份的销售情况,找出重点销售月份,从而制定制定经营策略与业绩月度及季度指标拆分。 # 为了方便观察数据,我们需要将数据根据年和月进行分组,并计算出每年每月的销售总额,再将其制作成年、月、销售额的数据透视表,最后我们折线图进行展示。 year_month = df.groupby(by=['Order-year','Order-month'])['Sales'].sum() #按照两列变成多层索引, year_month # # 将索引订单年转为一列数据 #第二个作业: 查询reset_index 什么意思level=[0,1] sales_year_month = year_month.reset_index(level=[0,1]) sales_year_month # # # 利用透视表的确定销售额预览表 sales_year_month = pd.pivot_table(sales_year_month, index='Order-month', columns='Order-year', values='Sales') # print(sales_year_month) # # # 绘制图形 sales_year_month.plot()
通过图表我们基本可以看出,该超市2011年-2014年每一年的销售额同比上一年都是上升趋势,所以很容易发现该超市的旺季是下半年,另外,我们在上半年销售额中发现6月份的销售额也是比较高的,所以可以在6月份开始加大一些运营成本,进而更大一步提高销售额,但是需要注意是下半年的7月份和10月份销售额会有明显的下降,可以针对这些下降的月份多举行一些营销活动。
4.4.新老客户数
老用户是企业生存的基础,新用户是企业发展的动力
#如果id一样就是重复客户, data = df.drop_duplicates(subset=['Customer ID']) new_consumer = data.groupby(by=['Order-year','Order-month']).size() #重新设置index #多层索引,变成单层索引 new_consumer2 = new_consumer.reset_index(level=[0,1]) new_consumer2 sales_year_month = pd.pivot_table(new_consumer2, index='Order-month', columns='Order-year', values=0) print(sales_year_month) # 下面,我们先来了解一下代码: # (1) 第一步,我们根据Customer ID列数据进行重复值的删除,保证数据集中所有的客户ID都是唯一的。 # (2) 第二步,我们根据Order-year和Order-month两个字段进行分组,并使用size()函数对每个分组进行计数。 # (3) 第三步,为了方便使用透视表对数据进行整理,需要先将索引转化成数据列。 # (4) 第四步,使用数据透视表功能,将年份作为数据的列索引,月份作为数据的行索引。
data = data.drop_duplicates(subset=['Customer ID']) new_consumer = data.groupby(by=['Order-year','Order-month']).size() new_consumer = new_consumer.reset_index(level=[0,1]) sales_year_month = pd.pivot_table(new_consumer, index='Order-month', columns='Order-year', values=0) print(sales_year_month)
根据图表可以看出,从2011年开始到2014年总体看,每一年的新增客户数是逐年减少的趋势,可以看出该网站对保持老用户是有效的,网站的运营状况较为稳定。但是,新客户获取率比较低,可以不定期的进行主动推广营销,从而增加新客户数。
4.5.用户价值度RFM模型分析
用户精细化运营
RFM的含义:
- R(Recency):客户最近一次交易时间的间隔。R值越大,表示客户交易发生的日期越久,反之则表示客户交易发生的日期越近。
- F(Frequency):客户在最近一段时间内交易的次数。F值越大,表示客户交易越频繁,反之则表示客户交易不够活跃。
- M(Monetary):客户在最近一段时间内交易的金额。M值越大,表示客户价值越高,反之则表示客户价值越低。
根据RFM模型我们只需要关注Customer ID、Order Date、Sales三个字段的计算即可
# 获取2014年数据 data_14 = df [df ['Order-year']==2014] data_14 # 获取三列数据 #因为这三列就可以组成模型 data_14 = data_14[['Customer ID','Order Date','Sales']] print(data_14.shape) #(17531, 3)
# 排序函数 def order_sort(group): return group.sort_values(by='Order Date')[-1:] # 将数据按客户ID分组 data_14_group = data_14.groupby(by='Customer ID',as_index = False) # 将每个分组对象的数据排序,并取出日期最大的数据 data_max_time = data_14_group.apply(order_sort) print(data_max_time)
# 为数据添加F列 data_max_time['F'] = data_14_group.size().values data_max_time['F'] # 为数据添加M列 data_max_time['M'] = data_14_group.sum()['Sales'].values print(data_max_time)
# 确定统计日期 stat_date = pd.to_datetime('2014-12-31') #当前时间 # 计算最近一次交易时间的间隔 r_data = stat_date - data_max_time['Order Date'] #最后一次交易的时间就是R # 为数据添加R列 data_max_time['R'] = r_data.values print(data_max_time)
section_list_F = [0,5,10,15,20,50] # 根据区间设置评分 grade_F = pd.cut(data_max_time['F'],bins=section_list_F,labels=[1,2,3,4,5]) # 添加FS评分列 data_max_time['F_S'] = grade_F.values data_max_time
# 设置M维度的评分 section_list_M = [0,500,1000,5000,10000,30000] # 根据区间设置评分 grade_M = pd.cut(data_max_time['M'],bins=section_list_M,labels=[1,2,3,4,5]) # 添加FS评分列 data_max_time['M_S'] = grade_M.values # 设置R维度的评分 import datetime section_list_R = [datetime.timedelta(days=i) for i in [-1,32,93,186,277,365]] # 根据区间设置评分 grade_R = pd.cut(data_max_time['R'],bins=section_list_R,labels=[5,4,3,2,1]) # 添加FS评分列 data_max_time['R_S'] = grade_R.values data_max_time
# 设置F维度高低值 data_max_time['F_S'] = data_max_time['F_S'].values.astype('int') # 根据评分平均分设置判别高低 grade_avg = data_max_time['F_S'].values.sum()/data_max_time['F_S'].count() # 将高对应为1,低设置为0 data_F_S = data_max_time['F_S'].where(data_max_time['F_S']>grade_avg,0) data_max_time['F_high-low']=data_F_S.where(data_max_time['F_S']<grade_avg,1).values # 设置M维度高低值 data_max_time['M_S'] = data_max_time['M_S'].values.astype('int') # 根据评分平均分设置判别高低 grade_avg = data_max_time['M_S'].values.sum()/data_max_time['M_S'].count() # 将高对应为1,低设置为0 data_M_S = data_max_time['M_S'].where(data_max_time['M_S']>grade_avg,0) data_max_time['M_high-low']=data_M_S.where(data_max_time['M_S']<grade_avg,1).values # 设置R维度高低值 data_max_time['R_S'] = data_max_time['R_S'].values.astype('int') # 根据评分平均分设置判别高低 grade_avg = data_max_time['R_S'].values.sum()/data_max_time['R_S'].count() # 将高对应为1,低设置为0 data_R_S = data_max_time['R_S'].where(data_max_time['R_S']<grade_avg,0) data_max_time['R_high-low']=data_R_S.where(data_max_time['R_S']>grade_avg,1).values data_max_time
# 截取部分列数据 data_rfm = data_max_time[['Customer ID','R_high-low','F_high-low','M_high-low']] def get_sum_value(series): return ''.join([str(i) for i in series.values.tolist()[1:]]) # 添加RFM字符串列 data_rfm['data_rfm'] = data_rfm.apply(get_sum_value, axis=1) dic = { '111':'重要价值客户', '101':'重要发展客户', '011':'重要保持客户', '001':'重要挽留客户', '110':'一般价值客户', '100':'一般发展客户', '010':'一般保持客户', '000':'一般挽留客户', }# RFM字符串数据映射成对应类型文字 data_rfm['data_rfm'] = data_rfm['data_rfm'].map(dic) print(data_rfm)
size = data_rfm.groupby(by='data_rfm').size()size = size.to_frame() size['rfm_pct'] = ["%.2f%%" % (i/sum(size.values) * 100) for i in size.values] print(size)
电商的客户的转化顺序:
一般挽留客户→一般发展客户→一般保持客户→一般价值客户→重要挽留客户→重要发展客户→重要保持客户→重要价值客户
那么处于不同阶段的客户,我们应该采取什么样的策略呢?
一般挽留客户:RFM三个值都低,说明已经是我们流失的客户。针对这批客户召回的成本一般会比较高,因为他们长时间没在平台有任何行为,有可能app都已经卸载。所以一般针对这种客户只会在特定的大型活动才采取全面的短信、广告、推送召回。比如在双十一、黑色星期五等大型购物狂欢节。或者说公司到了一个新阶段大量资金投入用户新增,比如我们看到过的“瓜分5个亿”、“无上限砍价”等活动。
一般发展客户:这类客户只是有近期购买行为但是购买商品利润低而且也不活跃。一般分两种类型,一种是刚注册的客户,另一种就是由于体验感一般接近流失边缘的客户。针对刚注册的用户一般会采取“新人大礼包”等优惠,一般“新人大礼包”会尽量多的覆盖平台上的不同商品品类,提高新客户了解平台产品的动力。而针对接近流失的客户应该从客服、物流等多角度追溯客户过去的不满原因,对平台进一步完善。
一般保持客户:这类客户只是频繁浏览,但是很久没有成交了。针对这类用户,一般会结合他最近浏览的商品进行相关优惠推送。促进他的成交行为。
一般价值客户:这类客户属于已经在平台上养成了自己的购买习惯,已经处于多次频繁购买的阶段,但是购买的商品价格都比较低,产生的利润也就低。对这类客户我们应该进一步分析他们属于购买力低还是大额商品有其他习惯成交的平台。针对前者一般不需要采取特别的措施,而针对后者我们应该时刻注意他的浏览商品动向,如果浏览远超过平时客单价的商品应该及时给予优惠政策。
重要挽留客户:这类消费金额较高,消费频次偏低,而且已经很久没有消费行为了。这种客户曾经算是平台的忠实用户而且能为平台提供比较大的利润但是很有可能马上就要流失了,所以应该进行重点挽留,如给他们更多关怀,应当主动客服沟通,建立平台形象,针对用户有什么不满意的地方应当及时解决,并给予优惠补偿。
重要发展客户:这类用户最近有消费,且整体消费金额高,但是购买不频繁。这种客户是有购买力的客户,应当重点维护,提升用户在消费中的体验感,比如加送“运费险”等等附加增值服务。
重要保持客户:最近一次消费时间较远,消费金额和消费频次比较高。这种客户一般是有网购习惯,但是最近却很久没有来消费。说明很可能已经流向别的平台。所以非常有潜力可挖,必须重点发展。要关注竞品的活动,做对比出合理方案。
重要价值客户:这类客户不用说了,RFM三个值都很高。是平台重点维护的客户,保证服务质量,保持客户在平台每次购物体验。
5.案例结论
从统计结果中看,该平台重要价值客户占总体17.54%,说明该公司已经沉淀了一批优良客户,而且这个比例还算是比较乐观。但有28.86%的重要保持客户,这批客户是曾高频购买且消费金额大的客户,但是这批客户近期没有成交行为说明已经有流失倾向,这批客户需要着重关注。另外一般发展用户也占了27.33%的比例,说明在用户新增的阶段做的还不错,但是其他类型的比例都偏少。这组数据说明了这个平台整体已经处于客户流失的阶段,用户整体活跃行为已经降低,需要维护现有忠诚的客户的同时,也要花精力在新用户往重要价值客户的转化上。
==========================================
分析每年销售额增长率:
- 目的:
衡量企业经营状况和市场占有能力、预测企业经营业务拓展趋势的重要指标,也是企业扩张增量资本和存量资本的重要前提。 - 结论:
结合上面的图表可以发现,2011年-2014年该超市的销售额在稳步上升,说明企业市场占有能力在不断提高,增长率2012年-2014年在增长后趋于平稳,说明企业经营在逐步稳定。同样我们根据销售和增长率,可以初步制定下一年度的销售额指标是:530万左右,当然具体销售额指标的制定还要再结合公司的整体战略规划。
各个地区分店的销售额:
1.各个地区(2011-2014年)分店的销售额占比(饼图)
结论:从占比图中可以看出APAC地区销售额占比最大为28.4%,而Canada地区的销售额占比最少,并且只有0.5%,说明市场几乎没有打开,可以根据公司的总体战略部署进行取舍,从而根据销售额占比分配下一年的销售额指标。
2.各个地区每一年销售额分析(组合柱状图。横:地区;纵:销售额;图例:年份)
结论:各个地区的2011年-2014年销售总额均是增长的趋势,在APAC地区和EU地区的增长速度比较快速,可以看出市场占有能力也在不短增加,企业市场前景比较好,下一年可以适当加大运营成本,其他地区可以根据自身地区消费特点,吸取上面两个地区的运营模式。
3.不同类别产品在不同地区的销售额(组合柱状图。横:地区;纵:销售额;图例:产品类别)
结论:
按照三个大的类型进行了区分,分别是Furniture(家具)、Technology(电子产品)、Office Supplies(办公用品)。通过上图我们大致可以看出,在各大地区销售额都比较高是电子产品,可以根据企业的整体战略部署适当的加大对各地区该品类的投入,以便扩大优势。
销售淡旺季:
- 目的:根据不同月份的销售情况,找出重点销售月份,从而制定制定经营策略与业绩月度及季度指标拆分。
对年份和月份进行group by ,对销售额进行加总
4条折线图(横:月份,纵:销售额,图例:年份) - 结论:
该超市2011年-2014年每一年的销售额同比上一年都是上升趋势,所以很容易发现该超市的旺季是下半年,另外,我们在上半年销售额中发现6月份的销售额也是比较高的,所以可以在6月份开始加大一些运营成本,进而更大一步提高销售额,但是需要注意是下半年的7月份和10月份销售额会有明显的下降,可以针对这些下降的月份多举行一些营销活动。
新老客户数:
老用户是企业生存的基础,新用户是企业发展的动力,所以企业的发展战略往往是在基于保留老用户的基础上不断地提升新用户数。
结论:
从2011年开始到2014年总体看,每一年的新增客户数是逐年减少的趋势,可以看出该网站对保持老用户是有效的,网站的运营状况较为稳定。但是,新客户获取率比较低,可以不定期的进行主动推广营销,从而增加新客户数。
利用RFM模型标记用户价值:
用户精细化运营
步骤:
1.分析的是2014年数据,统计时间为2014.12.31,且只需要三个字段,即:Customer ID、Order Date、Sales
2.我们对2014年数据按照Customer ID进行分组,然后再对每个分组的数据按照Order Date进行排序并获取出日期最大的那个数据。
stat_date = pd.to_datetime('2014-12-31') r_data = stat_date - data_max_time['Order Date'] data_max_time['R'] = r_data.values
3.算出RFM模型中的F(购买次数)和M(销售额总数)。
data_max_time['F'] = data_14_group.size().values data_max_time['M'] = data_14_group.sum()['Sales'].values
4.根据经验以及业务场景设定分值的给予区间
本项目中我们给定F的区间为[0,5,10,15,20,50],例如:1-5对应的为1、5-10对应的为2,依次类推;
M维度的区间为[0,500,1000,5000,10000,30000]
R维度的区间为[-1,32,93,186,277,365],但是R维度所对应的评分顺序应该与F和M的相反。 R越小,评分月越大
5.对每一个维度计算出对应的平均分,大于平均分的值的标记成1,小于平均分的值的标记成0。
6.完成对每个数据的RFM高低值的设置
dic = { '111':'重要价值客户', '101':'重要发展客户', '011':'重要保持客户', '001':'重要挽留客户', '110':'一般价值客户', '100':'一般发展客户', '010':'一般保持客户', '000':'一般挽留客户', }
7.看看不同类型的人群的占比
size = data_rfm.groupby(by='data_rfm').size()
- 大数据入门第一课 Hadoop基础知识与电商网站日志数据分析
- Excel VBA高效办公应用-第五章-销售数据的处理与分析-Part2(多条件筛选及判定)
- 链家二手房销售数据分析
- 电商数据分析方法——搭建数据指标体系
- 电商产品评论数据情感分析代码详解
- 用数据分析找到销售成功背后的真正秘密
- 销售行业ERP数据统计分析都有哪些维度?
- python数据分析练手小项目-汽车销售偷漏纳税人识别
- 【数据分析】电商数据挖掘之关联算法(一)
- 基于Echarts的销售企业经营数据分析-产品组合
- Black Fridy 销售数据分析
- CDNow网站销售数据分析
- [原创]如何利用BI搭建电商数据分析平台
- 淘宝电商用户行为数据分析及可视化—基于MySQL/Power BI(含代码)
- Spark大型项目实战:电商用户行为分析大数据平台
- 七、电商平台数据分析
- 汇纳客流分析数据助百货业应对电商冲击
- 野子电商数据分析
- 电商用户购买行为数据分析