18143453325 在线咨询 在线咨询
18143453325 在线咨询
所在位置: 首页 > 营销资讯 > 电子商务 > 电商销售数据分析-基于Python

电商销售数据分析-基于Python

时间:2023-03-15 23:36:01 | 来源:电子商务

时间:2023-03-15 23:36:01 来源:电子商务

一,背景

随着电商的不断发展,网上购物变的越来越流行,这样让各大电商得到了很大的发展机遇。同样,随着更多电商平台的崛起,对于电商卖家来说增加的不止是人们越来越高的需求,还要面对更多强大的竞争对手。面对这些挑战的时候,就需要能够及时发现店铺经营中的问题,并且能够有效的解决这些实际的问题,从而提升自身的竞争力。所以,根据已有数据对店铺整体运营情况分析,了解运营状况,以及对未来进行预测,已经成为一个电商以及运营等岗位必不可少的技能。

二:分析目标

对一家超市4年(2011年-2014年)的零售数据进行数据分析,数据分析的目标:

a, 分析每年销售额增长率。

b,各个地区分店的销售额。

c,销售淡旺季。

d,新老客户数。

e,利用RFM模型标记用户价值。

三,数据准备

四,数据采集

本章数据来源于数据科学竞赛平台

,总共51290条数据,24个字段。根据这些数据实现上述分析目标。

超市数据属性表:

五:了解数据基本情况

下载好数据后,我们使用Pandas导入数据,查看数据集的信息,快速理解数据。

import pandas as pd data= pd.read_csv('./dataset2011-2015.csv',encoding='ISO-8859-1')print('源数据的形状为:',data.shape)print('查看数据的类型:',data.dtypes)print('初步判断数据是否有缺失值:',data. info())print(data.head())使用read_csv读取数据的时候,需要根据csv文件存储时的编码格式,进行读取。csv常见编码格式:UTF-8GBK ISO-8859-1根据上面的代码结果,我们可以初步了解的数据的基本情况如下:

源数据的形状为:

各个字段的数据类型

初步判断数据是否有缺失值:

根据上面的结果,我们对数据已经有了初步的了解,24个字段中有7个字段是数字类型,这7个字段在去计算的时候是不需要转换类型的,其他字段的数据都是object类型,在获取数据的时候注意数据的类型,特别是日期字段的数据,整理数据的时候可以将其转换成时间格式,可以方便我们获取数

同时,也发现数据缺失方面只有Postal Code(邮编)字段有缺失值,而该字段对我们分析并不会产生影响,可以不用处理。

六:数据清洗

1,查看是否有缺失值

import pandas as pd data= pd.read_csv(r'superstore_dataset2011-2015.csv',encoding='ISO-8859-1')print('每个字段中是否含有空值:/n', data.isna().any())发现Postal Code字段含有缺失值。而该字段并不在我们的分析范围内,我们可以不处理该字段的缺失值,同时也保留了该字段所在数据其他字段的数据,这样可以确保分析的准确度。

2,查看是否有异常值

data.describe()出结果指标包括count,mean,std,min,max以及第25百分位,中位数(第50百分位)和第75百分位。通过观察该结果,发现数据集并无异常值存在。

七,数据整理

处理时间的类型,将其修改成datetime类型

data['Order Date'] = pd.to_datetime(data['Order Date'])print(data.dtypes)上面我们将Order Date(订单日期)列的数据类型成功修改成了datetime类型,因为在通过datetime可以快速的增加数据的维度,例如:年、月、季度等。

# 通过dt属性返回的对象中可以获取datetime中的年与日等数据data['Order-year'] = data ['Order Date'].dt.yeardata ['Order-month'] = data ['Order Date'].dt.monthdata ['quarter'] = data ['Order Date'].dt.to_period('Q')result = data [['Order Date','Order-year','Order-month', 'quarter']].head()display(data.head())七:具体分析目标

1,分析每年销售额的增长率

销售增长率=(本年销售额-上年销售额)/上销售额 * 100%

根据当前的数据对该超市进行2011年到2014年的销售增长率的趋势分析,并给出下一年的销售额建议

a,将数据按照年份进行分组,并计算出每年的销售总额

sales_year = data.groupby(by='Order-year')['Sales'].sum()print(sales_year)b,根据销售额增长率公式分别算出2012年、2013年和2014年的销售额增长率

sales_rate_12 = sales_year[2012] / sales_year[2011] -1sales_rate_13 = sales_year[2013] / sales_year[2012] -1sales_rate_14 = sales_year[2014] / sales_year[2013] -1print(sales_rate_12,sales_rate_13,sales_rate_14)用百分数的形式结果

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,sales_rate_13,sales_rate_14)
将数据进行图像形式展示
import matplotlib.pyplot as pltimport matplotlib as mpl# #由于百分比数据不支持绘图,所以重新求占比sales_rate_12 = sales_year[2012] / sales_year[2011] - 1sales_rate_13 = sales_year[2013] / sales_year[2012] - 1sales_rate_14 = sales_year[2014] / sales_year[2013] - 1print(sales_rate_12,sales_rate_13,sales_rate_14)# 设置字体#修改matplotlib 配置文件mpl.rcParams['font.sans-serif'] = ['SimHei']# 设置风格plt.style.use('ggplot')sales_rate = pd.DataFrame({'sales_all':sales_year, 'sales_rate':[0,sales_rate_12,sales_rate_13,sales_rate_14]})y1 = sales_rate['sales_all']y2 = sales_rate['sales_rate']x = [str(value) for value in sales_rate.index.tolist()]# 新建figure对象fig=plt.figure() # 新建子图1ax1=fig.add_subplot(1,1,1)# ax2与ax1共享X轴ax2 = ax1.twinx()ax1.bar(x,y1,color = 'blue')ax2.plot(x,y2,marker='*',color = 'r')ax1.set_xlabel('年份')ax1.set_ylabel('销售额')ax2.set_ylabel('增长率')ax1.set_title('销售额与增长率')plt.show() 结合上面的图表可以发现,2011年-2014年该超市的销售额在稳步上升,说明企业市场占有能力在不断提高,增长率2012年-2014年在增长后趋于平稳,说明企业经营在逐步稳定。同样我们根据销售和增长率,可以初步制定下一年度的销售额指标是:530万左右,当然具体销售额指标的制定还要再结合公司的整体战略规划。

2,各个地区分店的销售额

了解了该超市了的整体销售额情况之后,再对不同地区的分店的销售额占比情况进行分析,以便对不同地区分配下一年度的销售额指标,和对不同地区分店采取不同的营销策略。

a,我们先按照Market字段进行分组数据,整体看一下不同地区分店2011年-2014年的总销售额占比

sales_area = data.groupby(by='Market')['Sales'].sum()sales_area.plot(kind='pie',autopct="%1.1f%%",title='2011年-2014年的总销售额占比')从占比图中可以看出APAC地区销售额占比最大为28.4%,而Canada地区的销售额占比最少,并且只有0.5%,说明市场几乎没有打开,可以根据公司的总体战略部署进行取舍,从而根据销售额占比分配下一年的销售额指标

b,为了能更清晰的了解各地区店铺的经营状况,对各地区每一年的销售额进行分析。

sales_area = data.groupby(by=['Market','Order-year'])['Sales'].sum()sales_area# # # 将分组后的多层索引设置成列数据sales_area = sales_area.reset_index(level=[0,1])sales_area# # # 使用数据透视表重新整理数据sales_area = pd.pivot_table(sales_area, index='Market', columns='Order-year', values='Sales')sales_area# # # 绘制图形sales_area.plot(kind = 'bar',title = '2011年-2014年不同地区销售额对比') 从上面的图形中可以看出,各个地区的2011年-2014年销售总额均是增长的趋势,在APAC地区和EU地区的增长速度比较快速,可以看出市场占有能力也在不短增加,企业市场前景比较好,下一年可以适当加大运营成本,其他地区可以根据自身地区消费特点,吸取上面两个地区的运营模式

c,不同类型产品在不同地区的销售额占比,从而根据该占比适当的改善经营策略。

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) )所有产品按照三个大的类型进行了区分,分别是Furniture(家具)、Technology(电子产品)、Office Supplies(办公用品)。通过上图我们大致可以看出,在各大地区销售额都比较高是电子产品,可以根据企业的整体战略部署适当的加大对各地区该品类的投入,以便扩大优势。

3,销售淡旺季分析

了解了该超市了的整体销售额情况和不同类型产品在不同地区的销售情况之后,再对每年每月的销售额进行分析,根据不同月份的销售情况,找出重点销售月份,从而制定经营策略与业绩月度及季度指标拆分

需要将数据根据年和月进行分组,并计算出每年每月的销售总额,再将其制作成年、月、销售额的数据透视表,最后折线图进行展示

year_month = data.groupby(by=['Order-year','Order-month'])['Sales'].sum()# 将索引订单年转为一列数据sales_year_month = year_month.reset_index(level=[0,1])# 利用透视表的确定销售额预览表sales_year_month = pd.pivot_table(sales_year_month, index='Order-month', columns='Order-year', values='Sales')# 绘制图形sales_year_month.plot() 通过图表我们基本可以看出,该超市2011年-2014年每一年的销售额同比上一年都是上升趋势,所以很容易发现该超市的旺季是下半年,另外,我们在上半年销售额中发现6月份的销售额也是比较高的,所以可以在6月份开始加大一些运营成本,进而更大一步提高销售额,但是需要注意是下半年的7月份和10月份销售额会有明显的下降,可以针对这些下降的月份多举行一些营销活动。

4,新老客户数

将只要在该超市消费过客户就定义为老客户,反之为新客户。由于2011年的数据为起始数据,根据定义大部分客户皆为新用户,其数据没有分析价值,在分析的时候可以考虑。

dt = data.drop_duplicates(subset=['Customer ID'])new_consumer = dt.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年总体看,每一年的新增客户数是逐年减少的趋势,可以看出该网站对保持老用户是有效的,网站的运营状况较为稳定。但是,新客户获取率比较低,可以不定期的进行主动推广营销,从而增加新客户数

5,用户价值度RFM模型分析

RFM的含义

a,R(Recency):客户最近一次交易时间的间隔。R值越大,表示客户交易发生的日期越久,反之则表示客户交易发生的日期越近。

b, F(Frequency):客户在最近一段时间内交易的次数。F值越大,表示客户交易越频繁,反之则表示客户交易不够活跃。

c,M(Monetary):客户在最近一段时间内交易的金额。M值越大,表示客户价值越高,反之则表示客户价值越低。

根据R,F,M这三个维度,我们可以将客户分为以下8种类型

第一步,分析的数据是该超市2014年全年的数据,并假设统计的时间为2014年12月31日。现在我们利用下面代码获取数据2014年全年的数据:

# 获取2014年数据data_14 = data [data ['Order-year']==2014]# 获取三列数据#rfm 用这三列数据就可以制定rfmdata_14 = data_14[['Customer ID','Order Date','Sales']]data_14.head()由于RFM模型分别对应着Customer ID、Order Date、Sales这三个字段,所以我们只获取这三个字段的数据。

第二步,我们对2014年数据按照Customer ID进行分组,然后再对每个分组的数据按照Order Date进行排序并获取出日期最大的那个数据。

# 排序函数def order_sort(group):# print(group.sort_values(by='Order Date'))[-1:] 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.head())第三步,经过分组之后同样可以快速算出RFM模型中的F(购买次数)和M(销售额总数)。

# 为数据添加F列data_max_time['F'] = data_14_group.size().values# print(data_14_group.size())data_max_time['F'] # 为数据添加M列data_max_time['M'] = data_14_group.sum()['Sales'].valuesdata_max_time.head()第四步,目前已经获取到了2014年每个客户最后一次的时间了,现在需要根据假定同时间计算出最近一次交易时间的间隔。

# 确定统计日期stat_date = pd.to_datetime('2014-12-31')# 计算最近一次交易时间的间隔r_data = stat_date - data_max_time['Order Date']# 为数据添加R列data_max_time['R'] = r_data.valuesprint(data_max_time.head())第五步,经过上面四步分别计算出来RFM各个维度的数值,现在可以根据经验以及业务场景设定分值的给予区间,本项目中给定F的区间为[0,5,10,15,20,50],然后采用5分制的评分规则与上面分值区间一一对应,例如:1-5对应的为1、5-10对应的为2,依次类推。

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.valuesdata_max_time.head() 第六步,根据第五步的思路,首先确定M维度的区间[0,500,1000,5000,10000,30000],然后采用5分制的评分规则与上面分值区间一一对应。同理,确定R维度的区间为[-1,32,93,186,277,365],但是R维度所对应的评分顺序应该与F和M的相反。

# 设置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.valuesdata_max_time# 设置R维度的评分import datetimesection_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.valuesdata_max_time.head()第七步,上面给每条数据的RFM都设置了对应的评分,现在需要根据每一个维度,计算出对应的平均分,然后用对应的分数与平均值进行对比,大于平均分的值的标记成1,同理小于平均分的值的标记成0

# 设置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()grade_avg# # 将高对应为1,低设置为0data_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).valuesdata_max_time['F_high-low']# # 设置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,低设置为0data_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,低设置为0data_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).valuesdata_max_time.head()第八步,现在基本完成对每个数据的RFM高低值的设置,记下来就可以根据RFM的高低值对每个用进行类型标记了

# 截取部分列数据data_rfm = data_max_time.loc[:,['Customer ID','R_high-low','F_high-low','M_high-low']]def get_sum_value(series):# print([str(i) for i in series.values.tolist()]) return ''.join([str(i) for i in series.values.tolist()[1:]])# 添加RFM字符串列data_rfm['data_rfm'] = data_rfm.apply(get_sum_value, axis=1)data_rfm['data_rfm']dic = { '111':'重要价值客户', '101':'重要发展客户', '011':'重要保持客户', '001':'重要挽留客户', '110':'一般价值客户', '100':'一般发展客户', '010':'一般保持客户', '000':'一般挽留客户',}# # RFM字符串数据映射成对应类型文字data_rfm['data_rfm'] = data_rfm['data_rfm'].map(dic)print(data_rfm.head())print(data_rfm.tail())经过以上步骤,已经给所有的用户都设置好RFM的标签,现在让我们来看一下2014年不同类型人群占比。

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三个值都很高。是平台重点维护的客户,保证服务质量,保持客户在平台每次购物体验。

本次案例结论

通过对不同客户的行为分析,结合案例的结果。从统计结果中看,该平台重要价值客户占总体17.54%,说明该公司已经沉淀了一批优良客户,而且这个比例还算是比较乐观。但有28.86%的重要保持客户,这批客户是曾高频购买且消费金额大的客户,但是这批客户近期没有成交行为说明已经有流失倾向,这批客户需要着重关注。另外一般发展用户也占了27.33%的比例,说明在用户新增的阶段做的还不错,但是其他类型的比例都偏少。这组数据说明了这个平台整体已经处于客户流失的阶段,用户整体活跃行为已经降低,需要维护现有忠诚的客户的同时,也要花精力在新用户往重要价值客户的转化上。

关键词:分析,数据,销售

74
73
25
news

版权所有© 亿企邦 1997-2025 保留一切法律许可权利。

为了最佳展示效果,本站不支持IE9及以下版本的浏览器,建议您使用谷歌Chrome浏览器。 点击下载Chrome浏览器
关闭