月销售趋势分析主要实现按月份统计分析销售额和销量,并通过双折线图直观地体现销售的整体趋势,如图1.13所示。
图1.13 月销售趋势分析
从运行结果中得知:销售数据呈明显上升趋势,其中6月、10月和11月是销售旺季。为了实现月销售趋势分析,首先使用pandas模块的resample()方法和to_period()方法按月统计销售数据,然后通过matplotlib模块的plot()函数绘制双 y 轴图表,其中左侧 y 轴体现“成交码洋”,右侧 y 轴体现“成交商品件数”,实现过程如下(源码位置:资源包\Code\01\data_month_sales.py)。
(1)在项目目录下新建一个Python文件,并将其命名为data_month_sales.py。
(2)导入相关模块,代码如下:
import pandas as pd # 导入pandas模块 import matplotlib.pyplot as plt # 导入matplotlib模块
(3)读取Excel文件并抽取指定的数据,代码如下:
# 读取Excel文件 df=pd.read_excel('./data/data1.xlsx') # 抽取数据 df=df[['时间','成交商品件数','成交码洋']]
(4)按月统计数据,首先按“时间”对数据进行升序排序并将“时间”设置为索引,然后使用resample()方法和to_period()方法按月统计数据,代码如下:
# 排序并设置时间为索引 df1=df.sort_values(by=['时间']).set_index('时间') # 按月统计数据 df2=df1.resample('M').sum().to_period('M') print(df2)
运行程序,查看按月统计后的数据,如图1.14所示。
图1.14 按月统计数据
(5)数据处理完成后,接下来的任务是使用matplotlib模块的plot()函数绘制一个双 y 轴的图表。具体思路是:首先使用add_subplot()函数创建一个子图,然后通过twinx()函数为该子图添加一个与主 y 轴共享 x 轴的第二个 y 轴,并确保这个新 y 轴的刻度显示在子图的右侧,代码如下:
热销产品分析主要使用ABC分类法,该方法通过计算产品累计贡献率,将产品划分为A类、B类和C类,并随后进行数据可视化,以便直观地观察热销产品的分布情况,如图1.15所示。
图1.15 热销产品分析
从运行结果中得知:销售收入排名前三的产品分别是B16、B33和B18,销售收入排名后三的产品分别是B12、B10和B22。此外,各产品销售收入之间的差异巨大。
综上所述,根据ABC分类法,其中:A类产品贡献率为80%,包括B16、B33、B18、B27、B19、B30、B17、B26、B8、B25、B28和B13,这些产品属于热销产品,需要重点营销;B类产品贡献率为10%,包括B29、B14、B7、B9、B6和B5,这些产品比较重要,需要关注,并进一步挖掘增长点;C类产品贡献率为10%,包括B24、B11、B31、B32、B3等,这些产品一般重要,需要发挥潜力。
下面介绍热销产品分析的实现过程(源码位置:资源包\Code\01\data_hot_all.py)。
(1)在项目目录下新建一个Python文件,并将其命名为data_hot_all.py。
(2)导入相关模块,代码如下:
import pandas as pd # 导入pandas模块 import matplotlib.pyplot as plt # 导入matplotlib模块 import numpy as np # 导入numpy模块
(3)按照“商品名称”进行分组统计数据。首先读取Excel文件,然后抽取指定的数据,最后使用groupby()函数实现分组统计求和,代码如下:
# 读取Excel文件 df=pd.read_excel('./data/data1.xlsx') # 抽取数据 df=df[['商品名称','成交商品件数','成交码洋','加购人数']] # 按照商品名称进行分组统计 # 通过reset_index()函数将groupby()的分组结果重新设置索引 df1 = df.groupby("商品名称").sum().reset_index()
(4)由于“商品名称”过于冗长,可能会影响图表的可视化效果,因此我们可以为“商品名称”设置“商品ID”。这主要通过for循环和DataFrame对象的loc属性来实现,代码如下:
# 设置商品ID row_count = df1.shape[0] # 行数 for i in range(row_count): # 遍历行数 df1.loc[i,'商品ID']='B'+str(i+1) # 为商品ID赋值
(5)计算累计贡献率。首先将“商品ID”设置为DataFrame的索引,然后按照“成交码洋”的降序对数据进行排序,最后使用cumsum()函数和sum()函数计算累计贡献率,代码如下:
df1 = df1.set_index('商品ID').sort_values(by='成交码洋',ascending=False) # 设置索引并降序排序 df1['累计贡献率']=(df1['成交码洋'].cumsum()/df1['成交码洋'].sum()).round(2) # 计算累计贡献率 print(df1.head()) # 输出前5条数据
运行程序,输出前5条数据,以检验计算结果,如图1.16所示。
图1.16 累计贡献率
(6)按照ABC分类法进行分类。首先使用cut()函数切分数据并标记类别,代码如下:
# 使用cut()函数标记类别 df1['类别']=pd.cut(df1['累计贡献率'], [0,0.8,0.9,1], labels=[u"A类",u"B类",u"C类"])
运行程序,输出前5条和最后5条数据,以便查看分类后的数据,如图1.17所示。
图1.17 分类后的数据
(7)将分类数据保存为Excel文件,以方便日后使用,代码如下:
# 导出为Excel文件 df1.to_excel('data/data1_hot.xlsx')
(8)数据可视化。我们绘制双 y 轴图表,主要使用pandas模块提供的内置绘图函数。其中,柱形图用于展示“销售收入”,而曲线图用于展示“收入比例”。在曲线图上,我们添加累计贡献率的文本标签,同时绘制两条水平线,分别作为累计贡献率80%和90%的分界线,从而使得累计贡献率在图表中一目了然,代码如下:
通过1.6.2节内容,我们了解到热销产品中第一位的是B16。接下来,我们将分析该产品的环比增长情况,并通过双 y 轴图表来展示。在图表中,柱形图将展示“成交商品件数”,而折线图则展示“环比增长率”。具体如图1.18所示。
图1.18 热销单品环比增长情况分析
下面介绍热销单品环比增长情况分析的实现过程(源码位置:资源包\Code\01\data_hot_one.py)。
(1)在项目目录下新建一个Python文件,并将其命名为data_hot_one.py。
(2)导入相关模块,代码如下:
import pandas as pd # 导入pandas模块 import matplotlib.pyplot as plt # 导入matplotlib的pyplot子模块 import matplotlib.ticker as mtick # 导入matplotlib的ticker子模块
(3)筛选指定数据,然后按月统计数据,代码如下:
df=pd.read_excel('./data/data1.xlsx') # 读取Excel文件 df1=df[df['商品名称']=='Python从入门到项目实践(全彩版)'] # 筛选数据 df1=df1[['时间','成交商品件数']] # 抽取数据 df1=df1.set_index('时间').sort_values(by=['时间']) # 将时间设置为索引并进行升序排序 df2=df1.resample('M').sum().to_period('M') # 按月统计数据 print(df2)
(4)计算环比增长率。环比增长率反映本月比上个月增长了多少,公式如下:
在pandas中,我们可以使用shift()方法将数据移至上一条,从而得到上个月的数据,然后通过上述计算公式得到环比增长率,代码如下:
df2['成交商品件数']=df2.sum(axis=1) # 求和运算 df2['rate']=((df2['成交商品件数']-df2['成交商品件数'].shift())/df2['成交商品件数'])*100 # 环比增长率 print(df2.head()) # 输出前5条数据
运行程序,输出前5条数据,看一下环比增长率,如图1.19所示。
图1.19 环比增长率
说明
在运行结果中出现了NaN,NaN是“Not a Number”的缩写,即不是一个数,表示空值。之所以会出现空值,是因为没有上月数,也就是上一年12月份的数据。
(5)数据可视化。绘制双 y 轴图表,其中:使用matplotlib模块的bar()函数绘制柱形图,以展示“成交商品件数”;使用matplotlib模块的plot()函数绘制折线图,以展示环比增长率,代码如下:
说明
matplotlib.ticker模块主要用于设置坐标轴刻度的格式和位置。它提供了一些常用的刻度格式,如科学记数法、百分比和日期等,并允许用户自定义刻度格式。此外,它还可以设置刻度的位置、间隔和标签等,以满足不同用户的需求。常用的刻度和格式化如下:
AutoLocator:自动选择刻度间隔。
FixedLocator:指定固定的刻度位置。
MultipleLocator:指定刻度间隔。
NullLocator:不显示刻度。
FormatStrFormatter:指定格式化字符串。
加购人数和购买数量分析主要分析热销产品中A类产品的加入购物车人数和实际成交商品件数的对比情况,并通过结合柱形图和折线图来展示分析结果,如图1.20所示。
图1.20 加购人数和购买数量分析
从运行结果中得知:不同产品的购买数量及加购人数呈现基本同步变化的趋势。排名前三的产品分别是B33、B16和B27,其中B33和B16的购买数量差异不大,但它们与其他产品的购买数量相比,却有着显著的差异,是其他产品的三倍或更多。
下面介绍加购人数和购买数量分析的实现过程(源码位置:资源包\Code\01\data_addcart.py)。
(1)在项目目录下新建一个Python文件,并将其命名为data_addcart.py。
(2)导入相关模块,代码如下:
import pandas as pd # 导入pandas模块 import matplotlib.pyplot as plt # 导入matplotlib模块
(3)在热销产品中筛选A类产品,代码如下:
# 读取Excel文件 df=pd.read_excel('./data/data1_hot.xlsx') # 筛选A类产品 df=df[df['类别']=='A类'] # 抽取数据并按照“加购人数”进行降序排序 df1=df[['商品ID','成交商品件数','加购人数']].sort_values(by='加购人数',ascending=False)
(4)分别绘制折线图和柱形图,以便对实际成交商品件数和加购人数进行对比分析。其中:使用matplotlib模块的plot()函数绘制折线图,用于展示成交商品件数;使用matplotlib模块的bar()函数绘制柱形图,用于展示加购人数,代码如下:
接下来,我们对热销产品中不同种类产品的销量占比情况进行分析。我们首先为每种产品打上标签,然后按照这些标签对产品进行分组并统计每一组的销量,最后通过饼形图展示不同种类产品的销量占比情况,如图1.21所示。
从运行结果中得知:在热销产品中,Python的占比达到了44.5%,几乎占到总数的一半。因此,建议对这些产品实施重点营销策略,并继续拓展其周边产品,以增加产品种类的多样化。
下面介绍不同种类产品销量占比情况分析的实现过程(源码位置:资源包\Code\01\data_type.py)。
(1)在项目目录下新建一个Python文件,并将其命名为data_type.py。
(2)导入相关模块,代码如下:
import pandas as pd # 导入pandas模块 import matplotlib.pyplot as plt # 导入matplotlib模块
图1.21 不同种类产品的销量占比情况分析
(3)为产品打标签。我们通过“商品名称”字符串中包含的关键字为产品打标签。我们首先定义标签函数add_tag(),在该函数中使用if语句判断“商品名称”字符串中包含的关键字,然后应用该函数为产品打标签,代码如下:
运行程序,输出前5条数据,查看打标签后的结果,如图1.22所示。
图1.22 打标签后的数据
(4)分组统计数据。按照tag标签对数据进行分组统计求和,并根据“成交商品件数”进行降序排序,代码如下:
# 抽取数据 df=df[['tag','成交商品件数']] # 按照tag标签分组统计并进行降序排序 df1=df.groupby('tag').sum().sort_values('成交商品件数',ascending=False)
(5)数据可视化。使用matplotlib模块的pie()函数绘制饼形图,以便分析不同种类产品的销量占比情况,代码如下:
下面进行工作日与周末销量对比分析。我们首先对“日期”进行处理,从日期中找到工作日和周末,并对它们进行标记,然后对工作日5天和周末两天的数据进行分组统计求和,最后绘制双折线图以对这些数据进行对比分析,如图1.23所示。
从运行结果中得知:我们虽然凭直觉认为周末休息时购买的人数可能会更多,但经过实际对比分析发现,工作日的销量高于周末的销量。这种差异可能是由于工作日有5天,而周末只有两天。
下面介绍工作日与周末销量对比分析的实现过程(源码位置:资源包\Code\01\data_workday_weekend.py)。
(1)在项目目录下新建一个Python文件,并将其命名为data_workday_weekend.py。
(2)导入相关模块,代码如下:
import pandas as pd # 导入pandas模块 import matplotlib.pyplot as plt # 导入matplotlib模块
图1.23 工作日与周末销量对比分析
(3)对日期数据进行处理。我们主要使用dt对象的month属性和dayofweek属性获取月份和星期。通过dayofweek属性获取的星期是以数字形式表示的,其中0表示星期一,以此类推。然后,我们依据星期进行判断,将数字小于5的标记为工作日,将数字大于5的标记为周末,代码如下:
# 读取Excel文件 df=pd.read_excel('./data/data1.xlsx') # 获取并添加月份和星期(星期一=0, 星期日=6) df['月份'],df['星期']=df['时间'].dt.month,df['时间'].dt.dayofweek # 标记工作日和周末 df.loc[df[df['星期']<5].index,'标记']='工作日' df.loc[df[df['星期']>=5].index,'标记']='周末'
运行程序,查看标记后的数据,如图1.24所示。
(4)数据分组统计。首先抽取指定的数据,然后按照月份和标记分组统计求和,代码如下:
# 抽取数据 df=df[['月份','成交商品件数','标记']] # 按月份和标记分组统计求和 df1=df.groupby(['月份','标记']).sum() print(df1.head(6)) # 输出前6条数据
运行程序,看一下分组统计后前3个月的数据,如图1.25所示。
图1.24 标记后的数据
图1.25 分组统计后前3个月的数据
(5)绘制双折线图,主要使用DataFrame对象自带的绘图函数plot()直接对处理后的数据进行绘图,方便快捷,代码如下:
# 设置月份 month=['1月','2月','3月','4月','5月','6月','7月','8月','9月','10月','11月','12月'] # 解决中文乱码问题 plt.rcParams['font.sans-serif']=['SimHei'] # 将最内层的行索引转换为列索引然后绘制折线图 df1.unstack().plot(stacked=True) plt.xticks(range(1,13,1),month) # 设置x轴刻度及标签 plt.legend() # 显示图例 plt.show() # 显示图表