数据分析思路模板

数据分析思路模板

Yiuhang Chan

定量

  1. 明确目标:这是开始任何数据分析项目的第一步。明确目标意味着确定想通过数据分析解决的具体问题或达成的具体目标。这可能包括理解特定现象、预测未来趋势、识别模式或关系等。
  2. 数据处理:在这一步中,将收集相关数据并进行预处理。数据处理包括清洗(去除或纠正错误、不完整、不一致的数据)、格式化、结构化,以及可能的数据转换,以便于进一步分析。
  3. 数据分析:这一阶段是定量分析的核心,涉及使用统计方法、算法、模型等对数据进行深入探究。这可能包括描述性统计分析、推理统计分析、预测建模、聚类分析等。
  4. 数据展现:数据分析的结果需要以清晰、易懂的方式展现。这通常涉及数据可视化(如图表、图形、仪表板等),以及用于解释数据的文本描述。
  5. 报告撰写:最后一步是撰写报告,将分析过程、结果、以及洞察呈现给相关利益相关者。报告应该包括关键发现、数据分析的方法论、结论,以及可能的建议或行动方案。

明确目标

  1. 在对数据进行分析之前,首先第一步便是要明确目标。

  2. 明确目标这个环节往往需要做到以下三点,分别是:

    • 明确分析需求

    • 搭建分析框架

    • 收集分析数据

  3. 接下来结合防护服装厂案例,来了解一下在这三个环节都分别需要做些什么。

  4. 首先来学习一下如何明确分析需求。

注意

现状和痛点这两个事都要藏在心里面不要不要直接说(写这两个的都被优化了🤣)

明确分析需求

防护服装厂从 2020 年初开始售卖防护服,到 7 月初的时候,营销总监发现账目上已经开始出现亏损。总监十分焦虑,想要在短时间内快速找到亏损的原因,以及对应的解决策略。

从总监遇到的难题中不难发现,这次的任务需要解决两个问题,分别是:

  • 找到亏损原因
  • 找出对应的解决策略

在明白了这次的任务需要做什么以后,接下来就要思考如何去解决这些问题了。而要想解决问题,往往就需要搭建一个分析框架,系统地指导我们该如何去解决问题。

报告制式
1
2
3
4
5
## 一、背景
某某科技公司,运营了一家小型的****工厂,该厂经营状态过往处于不稳定的状态,在今年6月底,经营开始处于亏损状态。通过本次对该厂历史经营数据的分析,帮助公司推断该厂的发展,并对该厂的亏损问题处理提供建议。

## 二、目的
探寻该厂的亏损问题的原因、及下一阶段的经营发展趋势,并对防护服装厂的亏损问题处理提供建议。

搭建分析框架

通过刚才的分析,已经知道了这次任务首先要做的就是找到防护服付账厂亏损背后的原因。

而亏损意味着利润为负,所以本质上我们要研究的是防护服装厂的利润情况。

订单量、单价、成本以及销售额都是会影响防护服付账厂利润的。

现在的问题是,即便知道了这四个因素会影响防护服付账厂的利润,接下来该如何动手去分析呢?到这里思路依旧不明朗。

尤其是这些因素,彼此之间又存在一些关联,互相影响。比如想研究订单量的变化情况,结果发现订单量对利润可能不构成直接影响。

公式拆解法

一种比较适合这个问题场景的方法:公式拆解法。首先来了解一下公式拆解法是什么。

公式拆解法就是利用数学公式,将会影响因变量的因素按照层级关系罗列出来。然后通过分析这些因素的变化情况,来推演因变量是如何受到这些因素影响的,如下图所示:

首先从最根本的研究对象,或者说因变量开始拆解。由于防护服装厂的亏损本质上就是利润为负,那么利润就是最终想要研究的对象,放在最顶层

在对销售额拆解完毕以后,正常情况下应该思考成本会和哪些因素有关。

不过这里有个好消息,就是之前的一位员工在计算防护服付账厂各月成本的时候,已经求得防护服付账厂在 2020 年 1 月到 6 月期间,各月成本/工资/投放/房租/水电暖几乎没有变化,成本这块儿可以忽略不计。

所以利润这个因素可以看作只受到销售额的影响,之后没有必要对成本继续拆解了。

当然,这个拆解的过程是可以不断细分下去的,但是有一点要考虑,数据的采集成本。

比如说想要继续研究订单量这个因素,我们可能会觉得这和市场的供货量有关,于是就想要去采集 2020年年初到 6 月份期间市场上防护服装厂的总产能,想通过产能的变化来分析订单量的变化原因。

防护服付账厂的订单量很有可能是被这部分”大客户“所主导的。

如果因为某些原因,“大客户”出现了比较严重的流失,那么就会对订单量产生比较大的影响。

基于这条拆解思路,可以根据公式:订单量 = 订单量(省份1) + 订单量(省份2) + 订单量(省份3)+ …,对订单量进行进一步的拆解

到这里就已经利用公式拆解法对防护服付账厂的利润情况进行了拆解。

从搭建的模型来看,后续的分析需要用到以下四层信息:销售额、订单量、防护服付账单价、订单来源省份。

报告制式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
## 三 、分析思路
### 3.1方法:
利润 = 销售额-成本,现已知1-6月份防护服装成本是变动微小,故本次分析主要从“销售额”进行分析。

### 3.2总方法:
通过销售额及其影响因子的分析,对过往销售额变化的规律、变化原因进行剖析

### 3.3公式:
销售额 = 订单量 × 单价
订单量 = 省份1+省份2...+省份n

### 3.4分析框架:
分析各月的“销售额”变化趋势,分析变化规律与原因。
分析各月“订单量”的变化趋势,分析变化规律与原因。
分析各月“单价”的变化趋势,分析变化规律与原因。
分析各月各省份“订单量”的变化趋势,分析变化规律及原因。

数据收集

1
2
3
4
5
6
# 导入 CSV 数据
import numpy as np

protective_clothing = np.loadtxt('mask_data.csv', dtype = str, encoding = 'utf-8')

print(protective_clothing)

numpy库为读取各种文件类型的数据提供了非常简便高效的方法。

np.loadtxt('path', dtype , encoding ) 就是其中一种高效读取 csv 文件的方法.

这个方法有很多参数,这里先介绍三种最常用的:pathdtypeencoding

对于参数 path,需要传一个文件路径给它,可以是相对路径,也可以是绝对路径。这里出于方便,就可以传一个相对路径给参数 path

对于参数dtype,根据业务需要转换成我们想要的数据类型,在该案例中,因为数据是字符串类型,我们就要转换成dtype = str

对于参数 encoding,需要传一个文件编码格式给它。文件编码格式的选取需要根据所读文件的编码格式来定。

从拆解好的思路中不难发现,需要用到的信息有:销售额、订单量、单价以及省份信息。

同时,刚才也分析过我们需要用到时间这个维度的信息,与之对应的日期这一列数据,也存在与我们的数据之中。

不过在观察各列的数据时,数据的异常情况,如下图所示:

报告制式
1
2
## 四、数据来源
从公司数据库中导入营销数据mask_data.csv,原始数据一共包含101942行,数据的结构如下:

小结

数据处理

注意

数据清洗和数据处理不是一回事,数据清洗属于数据处理的一个环节

数据清洗

1
2
3
4
5
# 导入Pandas库并将其简化为pd
import pandas as pd # 导入数据分析库
# 读取本地口罩厂的数据
mask_data = pd.read_csv("mask_data.csv")
print(mask_data)
缺失值
处理缺失值

使用df.info()方法查看数据集信息

其中,日期,省,订单量,单价,销售额这些列的非空数据都比数据总量要小,说明都有缺失值

pandas 库中,我们可以使用isna()方法来查找DataFrame 对象 以及 Series 对象中的缺失值。它可以将查找结果以 DataFrame 对象或者 Series 对象的形式进行返回。df.isna()返回的是 DataFrame 对象,Series.isna() 返回的就是 Series 对象。

protective_clothing.isna()

1
2
# 查看数据后5行
protective_clothing.tail()
删除缺失值
1
2
3
# 删除所有缺失值

mask_data_na_clean = mask_data.dropna()
小结
重复值
处理重复值

重复值很好理解,就跟字面意思一样,指的是表格中重复出现的数据。在多数情况中,重复值都是完全相同的数据。

重复值处理的第一步和缺失值一样,还是要先查找重复值。

我们可以直接使用df.duplicated() (中文意思:重复的)方法来查找DataFrame 对象中的重复数据。

使用 df.duplicated() 方法会返回一个 Series 对象,找出所有重复值。重复为 True,不重复为False

1
2
# 查找 protective_clothing 中的重复行
mask_data_na_clean.duplicated()
1
2
# 查看 protective_clothing 中的重复数据
mask_data_na_clean[mask_data_na_clean.duplicated()]
1
2
3
4
# 直接删除所有重复值
mask_data_na_dup_clean = mask_data_na_clean.drop_duplicates()
# 查看 protective_clothing 中的重复数据
mask_data_na_dup_clean[mask_data_na_dup_clean.duplicated()]

在运行结果中我们能看见mask_data_na_dup_clean的表头下面是空的,说明到这里已经没有重复数据了。值得一提的是,df.drop_duplicates() 方法并不会将所有重复的行都删除。

小结
异常值
处理异常值

有时数据中有一个或多个异常大或异常小的数值,超出了这份数据实际的限定范围,这样的数值被称为
异常值。

我们在数据清洗中要先对异常值进行识别,因为它有可能是一个错误的数值。

对于异常值,我们首先要做的是检查数据是否存在异常。若数据存在异常我们则需要抽取限定范围的数据,过滤异常值。

检查异常值

  • 检查数据是否存在异常的方法 —— describe()
  • describe 单词在英语里是描述的意思,而在 pandas 库中 describe() 方法则可以查看 Series 对象或者 DataFrame 对象的描述性统计信息。
1
2
# 查看 protective_clothing 的描述性统计信息
mask_data_na_dup_clean.describe()

抽取数据范围,在pandas库中,有一种筛选数据的方法叫做布尔索引,使用df['列索引'] 来提取某一列的信息。在 pandas 库中,我们还可以在 df[] 中通过表达式的形式来提取一定范围的数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 查看单价小于等于200的数据
mask_data_na_dup_clean[mask_data_na_dup_clean['单价'] <= 200]

# 查看单价小于等于200的数据
mask_data_na_dup_clean['单价'] <= 200

# 筛选单价小于等于200的数据
mask_data_na_dup_s200_clean = mask_data_na_dup_clean[mask_data_na_dup_clean['单价'] <= 200]

# 查看防护服装厂数据的描述性统计信息
mask_data_na_dup_s200_clean.describe()

# 筛选订单量大于0的数据
mask_data_na_dup_l0_s200_clean = mask_data_na_dup_s200_clean[mask_data_na_dup_s200_clean['订单量'] > 0]

# 查看mask_data的描述性统计信息
mask_data_na_dup_l0_s200_clean.describe()
mask_data_na_dup_l0_s200_clean.info()
小结

数据整理

转换日期数据
1
2
3
mask_data_na_dup_l0_s200_clean_date_fot = pd.to_datetime(mask_data_na_dup_l0_s200_clean['日期'], format = '%Y-%m-%d')
# 查看date_data
print(mask_data_na_dup_l0_s200_clean_date_fot)
提取月份信息
1
2
3
4
# 提取日期数据中的月份信息
month_mask_data = mask_data_na_dup_l0_s200_clean_date_fot.dt.month
# 查看month_data
print(month_mask_data)
增加新列
1
2
3
4
# 将月份数据添加到原数据中
mask_data_na_dup_l0_s200_clean['月份'] = month_mask_data
# 查看原数据
print(mask_data_na_dup_l0_s200_clean)
保存文件
1
2
# 保存清洗干净的数据,并取消写入行索引
mask_data_na_dup_l0_s200_clean.to_csv('mask_data.csv', index = False)

报告制式

1
2
3
4
5
6
7
8
9
10
11
## 五、数据处理
### 5.1清洗数据:
缺失值
重复值
异常值
### 5.2 整理数据:
多增加【月份】这一列,时间维度
### 5.3 清洗结果:
我们对以上三种数据均进行了删除处理,其中清洗前数据一共有101942,清洗后数据一共有99485行。
清洗数据占比:占比2%
清洗前后数据量变化极小,因此可以忽略对结果的影响。

小结

数据分析

根据前面的分析拆解,我们知道本次分析的重点是—销售额,订单量,单价,各省订单量随着时间变化的趋势及其变化原因。

那么,我们可以通过分组聚合对每一组数据进行描述性统计分析,然后利用折线图进行变化趋势的分析。

防护服装厂的任务,需要解决总监的两个问题—找到亏损原因、找出对应的解决策略。

分组聚合,统计数据

本次分析的影响因素是销售额、订单量、单价、各省订单量,而且是以一个月为颗粒度,进行时间维度上的变化趋势和原因分析。

清洗后的数据mask_data_clean,它的列索引中包含着我们需要的销售额、订单量等数据。

以销售额为例,如果要分别查看 1 月到 6 月以来的销售额,可以根据月份对数据mask_data_clean进行分组。

我们可以计算出销售额的总数,因为它代表着这个月销售额的总体情况,可以通过对比它的上升或下降,查看其每月变化。

首先要根据月份对数据集进行分组groupby,同时还需要对销售额列进行一次聚合计算,计算出销售额的总和sum

1
2
3
4
5
6
7
8
9
10
# 导入Pandas库并将其简化为pd
import pandas as pd # 导入数据分析库
# 读取本地口罩厂的数据
mask_data = pd.read_csv("mask_data_clean.csv")

# 获取每月销售额总数
sales_income = mask_data_clean.groupby('月份')['销售额'].sum()

#查看数据
sales_income

可以看到,打印的结果是一个 Series 对象,它的值是销售额的总数,行索引是月份。

根据数值已经可以大致看出,1-3 月总销售额增加, 3-6 月则在下降。基于这样的每月销售额统计数据,才能方便地进入后续趋势分析步骤中。

那么应该如何去分析其他3个影响因素呢?上一节课我们提到过公式拆解法搭建我们的分析框架和方法,销售额 = 订单量*单价

根据对各月销售额的分析,我们可以总结出:不同影响因素进行分组聚合操作时,有两个要点。

  • 根据什么进行分组;
  • 选择什么代表性的统计方法,进行聚合计算。

那么对于各月订单量、各月单价、各月各省订单量,应该根据什么进行分组,应该选择什么统计性数值呢?

例如对不同班级、不同班级不同性别、不同班级不同性别是否带眼镜等等情况都是如何一一进行分组聚合的。

​ 比如,不同班级不同性别的分组聚合方式是这样的:

不过单价的平均值可以反映出某一商品在一定时期内的平均价格,一定程度上可以体现普遍的价格数量。因此选择平均数作为单价的统计性指标。

1
mask_data_clean.head(3)
1
2
3
# 获取各月总订单量
order_number = mask_data_clean.groupby('月份')['订单量'].sum()
order_number

不错,它同样能够体现出这个月所有订单量的变化情况,1-3 月数量上升,3-6 月数量下降。

接下来来看每月单价,找一下如何计算单价的平均值:

1
2
3
4
5
# 获取每月平均单价
month_price = mask_data_clean.groupby('月份')['单价'].mean()

# 查看数据
month_price

要用列表来包含两个用于分组的索引

1
2
3
4
5
# 获取各省各月总订单量
month_order = mask_data_clean.groupby(['省', '月份'])['订单量'].sum()

# 查看数据
month_order
1
2
3
4
5
# 获取各省各月总订单量
month_order_2 = mask_data_clean.groupby(['月份', '省'])['订单量'].sum()

# 查看数据
month_order_2

终端打印出的 Series 数据,它的外层索引是月份,内层是省份,因此从上往下,看到的是每个月不同省的总订单量数据。

  • 通过 month_order,我们能大致看出某个省的总订单量随月份的变化情况;
  • 而通过 month_order_2 ,则可以看出某个月时不同省份总订单量的变化情况。

折线分析,确定趋势

首先还是来看每月总销售额,前面我们将它存储在变量 sales_income 中,怎么画出对应的折线图

1
2
3
# 获取每月销售额总数
sales_income = mask_data_clean.groupby('月份')['销售额'].sum()
sales_income

这是一个Series对象,行索引是月份,值是每月总销售额。因此可以直接用 pandas 的plot()方法画图。

1
2
3
4
5
# 导入matplotlib库的pyplot模块
from matplotlib import pyplot as plt
plt.rcParams["font.sans-serif"]=["SimHei"] #设置字体
plt.rcParams["axes.unicode_minus"]=False #该语句解决图像中的“-”负号的乱码问题
sales_income.plot(kind = 'line', figsize = (7,7) ,title = ('画出各月总销售额的折线图'))

直接使用前面的Series对象,就可以画出来一个以月份为横坐标,以单位数值为纵坐标,总销售额为数据点的折线图。

按理来说,画出各月总销售额的折线图之后,就可以继续去分析其统计值的变化趋势了。

但是下面我们会先把“各月订单量、单价、各省订单量”剩下 3 个折线图都画出来之后,再进入下一步的趋势分析。

因为这 4 个影响因素关系密切:订单量不变时,单价越高销售额也会越高;同理单价不变时,订单量越多销售额也会越高。

如果这些因素的变化趋势也呈现这样的某些共性,就可以综合起来进行分析,就更容易抓住关键性的影响因素,可以聚焦问题。

1
2
# 画出各月总订单量的折线图
order_number.plot(kind = 'line', figsize = (7, 7), title = '各月总订单量趋势图')

可以得到以月份为横坐标,单位数值为纵坐标,平均单价为数据点的折线图,单位为元。

最后来看各省各月总订单量的变化趋势,它的特殊之处在于,需要通过多条折线图来直观体现出不同省份不同月份的区别。

前面我们将各省各月的统计数据存储在变量 month_ordermonth_order_2中,它们是两个 Series 对象。

但是多条折线图需要基于 DataFrame 数据来画,因此我们需要使用 unstack() 方法将 Series 对象变为 DataFrame 对象。

1
2
3
4
5
# 将month_order1转换为DataFrame,存储在month_order_df中
month_order_df = month_order.unstack()

# 查看month_order1_df中的数据
month_order_df
1
2
# 根据month_order_df绘制多条折线图,标题为'各月各省总订单量趋势图'
month_order_df.plot(kind = 'line', figsize = (7, 7), title = '各月各省总订单量趋势图')

我们画出来的是各月各省总订单量趋势图,它以不同颜色线条表示不同月份,以省份为横坐标,以数值单位为纵坐标,以订单量数值为数据点形成的折线图。

1
2
3
4
5
# 将month_order_2转换为DataFrame,存储在month_order_2_df中
month_order_2_df = month_order_2.unstack()

# 根据month_order2_df绘制多条折线图,标题为'各省各月总订单量趋势图'
month_order_2_df.plot(kind = 'line',figsize = (7, 7), title = '各省各月总订单量趋势图')

现在我们已经画完了 4 个需要的折线图,接着就可以具体观察折线图,详细分析不同影响因素的变化趋势

观察折线图,有3个要点,

​ 一是整体的走势

​ 二是走势的规律性

​ 三是走势的波动

我们可以直接通过折线图的线条倾斜程度,看出走势波动的强烈程度,比如下图就是不同变化程度的体现.

基于这三个要点,可以让我们更加全面地描述折线图的趋势特征。接下来我们整体来看一看四个影响因素随月份变化时对应的折线图。

可以发现无论各月的总销售额、总订单量、平均单价,以及各省在各月的总订单量,变化趋势有很大的相似性:

1)在 1 月到 3 月的折线是随着时间增长而增加,整体呈增加趋势,其中 2 月到 3 月增长快速;3 月之后整体呈下降趋势,3 月到 4 月出现了“急跌”。

2)目前的折线中未出现多个类似形状的起伏波动,未体现出任何规律性。

3)而且图中只有一处波动起伏,在这个起伏的最高点,对应着 3 月的数据,此处为最大值。

本质上,趋势是由背后的原因推动的。看趋势,更得看背后的原因,而不是单纯的看着结果走势想当然。

因此接下来的时间,我们来分析防护服装厂各项影响因素的统计值都在“走下坡路”的原因,给总监一个“交代”。

原因剖析,聚焦问题

这里趋势变化非常明显,最大值(转折点)为 3 月,因此我们重点关注这个值,以其特殊性作为突破口。

根据订单量、单价的变化,我们可以知道,3 月之前,工厂的防护服装需求量和价格都增长猛烈,3 月之后却又出现大幅下降。

按理来说,防护服装属于医用防护品和日用生活品,不受季节、时间的影响。一般其需求源头比较稳定,物价也很稳定。

但是对比 1-3 月份总订单量的变化,其纵坐标的值是 0 到 2,但是单位是百万。因此是从 1 月份的万余盒,增长到 2 月份的 30 余万盒,突然涨到 3 月份 196 万余盒,变化迅猛。

另外通过折线图也能够发现趋势变化的强烈程度,比如 3 月到 4 月的订单量,就是一个“急跌”,订单量一下子缩水了 100 多万!

因此认为,要想在两三个月内迅速改变防护服装的供需关系,应该是属于社会性问题的外部冲击。

与防护服装使用的历史一致,几乎每次大的普及推广都是受传染性疾病或空气污染等外部影响。

因此这里排除业务内部原因,比如偶发性降价促销活动带来的客流量上涨与衰退,以及工厂竞争能力降低带来的市场占有率从高到低等等内部问题。

因为这些情况都属于常规运营问题,造成的影响远不会如此剧烈。

实际上,从 2020 年 1 月底开始,国内就蔓延出了新冠的传染性疾病,到了 3 月份,疫情感染人数才逐渐得到控制。

当然我们还是要结合疫情的情况,进行材料的佐证,这样才能尽量合情合理的去解释所发生的现象。

疫情最严重的时期为 2 月份,2 月初电视中还经常出现药店防护服装断供的新闻,3 月中下旬开始,全国陆续开始复工,人群流动性增加的情况下,防护服装的需求也是达到了最高点。

而且我们也可以看到,各省的订单量变化中,以湖北省的变化最为强烈,在 2020年的新冠疫情中,湖北省是重灾区,全省 5927 万人口,是非常大的需求缺口。

据说我们的工厂整个 2-3 月都在加班加点进行生产,但是防护服装的价格与销量都还是只增不降,说明需求根本无法及时得到满足。

而到 3 月之后,疫情好转,全国各地陆续放松,尤其是不再要求必须在公众场合佩戴防护服装,人们对于防护服装的需求迅速回落,一直到 6 月销量和价格都仍在下落的过程中。

可以说,2020 年 1 月到 6 月,由于新冠疫情的影响,防护服装的供需关系发生了很大的波动变化,导致工厂防护服装的订单量、价格以及整体销售额也自然随之发生变化。

但如果直接给出结论,就只是空口无凭了,做数据分析就是要能够发掘和解释其背后的逻辑。

深入洞察,提出对策

说到问题根源,其实还是一个供需关系,如果防护服装厂商在供需矛盾中不占优势,想要继续维持原来高价格高销量的情况几乎是不可能。

因为人们的购买标准,将从“能用”升级为性价比高、质量好、服务好等更复杂的行业竞争力问题上。

因此当疫情减少,刚性需求减少后,防护服装行业的市场竞争将会越发激烈。

1 月这段时间基本不属于疫情影响范围内,比较能够体现出日常情况下人们对于防护服装的需求。我们可以以此对比一下疫情前后,订单量和单价的情况:

如果这种状态下,6 月份防护服装厂是处于亏损,那么未来这段时间,防护服装厂将继续处于亏损状态。

众所周知,“比亚迪”作为一个汽车企业,由于这次生产转型,其在防护服装行业也占有了一席之地。因此,现在的情况是危机也是转机,是打开稳定市场的好机会。

基于这样的分析,跟总监提出两种不同的建议:

1)公司可以对防护服装厂进行改革,不过对于工厂的优势,改革的重点及规划,还有待进一步对产品、营销体系等情况的分析。

2)如果公司不对防护服装厂进行新的投入和改革,防护服装厂将会持续亏损,建议尽早对防护服装厂做转让处理。

当然,还有第三种方案,那就是基于国际局势考虑,目前南半球及欧美国家,由于气候及政策等原因,新冠疫情的危机是越演愈烈。
预计对于疫情为加重趋势的国家,防护服装的需求量仍会比较高涨。

3)如果可以及时打开国际销售渠道,并维持相对较低的成本,工厂将仍能保持供需矛盾中的优势地位,维持高单价高销量的营收情况。

小结

我们说整个数据分析过程就是根据分析目的,用适当的分析方法及工具,对数据进行处理和分析,提取有价值的信息,其目的是总结出所研究对象的内在规律。

在实际工作中,数据分析能够帮助管理者进行判断和决策,以便制定适当的策略与采取相应的行动。因此掌握数据分析能力对于我们的工作会有很多的帮助。

数据展现

选对图表

不同图表的适用场景

不同的图表一般会有不同的适用场景,我们将折线图、柱状图和饼图进行简单对比。

可以清晰地看到,折线图主要是呈现数据变化的趋势;柱状图让数值大小的比较更加明显;至于饼图,能够直观地显示各部分相对于整体的占比。

多条折线图兼具了折线图和柱状图的优势,能够比较多组数据在同一个维度上的趋势,比如上一节课绘制的“各省各月订单量趋势图”就是各个省份的订单量在同一个维度“月”进行的比较。

明确数据展现的目标

思路1

各月的总销售额、总订单量、平均单价以及各省在各月总订单量,都出现了1-3月迅猛增长呈增长趋势,3-6月呈下降趋势的情况。

使用折线图呈现总销售额、总订单量以及平均单价在1-6月之间的变化趋势是合理的,但是我们仔细观察这三张图就会发现:

  1. 观察 y 轴,不能很快知道数据的数量级和单位;
  2. 图中折线颜色均是默认的蓝色,放在一起对比不容易区分;
  3. 图中折线对应的数据标记点不够明显,无法很好地与坐标轴上的值进行对应;
  4. 此外,图中的图表标题、坐标轴刻度、坐标轴标题等字体都太小了,看不清楚。

所以,我们重点调整这几张图的坐标轴标题、折线以及数据标记点样式,并调整图表标题、坐标轴刻度、坐标轴标题等字体大小。

用多条折线图呈现各省在各月总订单量的变化趋势是合理的,但同样也存在一些问题:

  1. 观察 y 轴,不能很快知道数据的数量级和单位;
  2. 图中折线对应的数据标记点不够明显,无法很好地与坐标轴上的值进行对应;
  3. 此外,图中的图表标题、坐标轴刻度、坐标轴标题等字体都太小了,看不清楚。

因此,我们重点调整多条折线图的坐标轴标题、折线以及数据标记点样式,并调整图表标题、坐标轴刻度、坐标轴标题重点调整的字体大小。

思路2

通过对比 1 月和 6 月的订单量、平均单价,发现 6 月的订单量虽然比日常(1月)要高,但是平均单价已经降至比 1 月还低。

使用折线图呈现订单量、平均单价在 1 月和 6 月的数值比较是不合理的,建议用柱状图。除此之外:

  1. 图中 y 轴均缺少标题,不能很快得知它们的数量级;
  2. 对 1 月和 6 月的数值比较,但是图中没有数值,而是添加了额外的标注;
  3. 强调 1 月和 6 月进行对比,但是颜色没有做专门的区分。
  4. 此外,图中的图表标题、坐标轴刻度、坐标轴标题等字体都太小了,看不清楚。

因此,我们绘制柱状图,并重点关注该柱状图的坐标轴标题、数据标签以及柱子样式,并调整图表标题、坐标轴刻度、坐标轴标题重点调整的字体大小。

绘制各月总订单量趋势图

1
2
3
4
5
6
7
8
# 导入pandas库
import pandas as pd
# 读取清洗好的数据
mask_data_clean = pd.read_csv('mask_data_clean.csv', encoding='utf-8')

# 获取各月总订单量
order_number = mask_data_clean.groupby('月份')['订单量'].sum()
order_number

x 坐标值是月份的信息,y 坐标值是每个月对应的口罩订单量合计值。

我们发现折线图中每一个点的 x 坐标值就对应着 order_number 对象左边的索引,而折线图中每一个点的 y 坐标值就对应着 order_number 对象右边的数据。下面就以两个点为例:

可以用 Series 对象的 index 和 values 属性分别获取左边的索引和右边的数据。

首先看一下 index 属性

1
2
3
order_number.index

# Int64Index([1, 2, 3, 4, 5, 6], dtype='int64', name='月份')

这里返回的是一个 index 对象,里面存储了月份信息。

我们再来看一下 values 属性

1
2
3
order_number.values

# array([ 13852., 389319., 1961480., 546276., 158188., 22222.])

确定了 x/y 坐标值,我们就调用折线图绘图函数 plt.plot() 开始绘图。

1
2
3
4
5
6
7
8
x = order_number.index
y = order_number.values

# 生成画布,并设置画布的大小
plt.figure(figsize=(6, 6))

# 绘制折线图
plt.plot(x, y)

绘图函数 plt.plot()本身是很强大的,通过调整其中的参数还可以进一步调整折线的样式

基于刚才确定的目标,我们重点调整坐标轴标题、折线以及数据标记点样式,并调整图表标题、坐标轴刻度、坐标轴标题的字体大小。

先看线条的宽度和颜色,需要用到的参数分别是 linewidthcolor

参数 linewidth 可以设置线条的宽度,常见为数值类型。

参数 color 可以设置线条的的颜色。下图为 matplotlib 库支持的颜色,只需要向 color 传入颜色块旁边对应的英文单词即可,常见为字符串类型。

设置线条的宽度为3:linewidth=3,颜色为红色:color='r'(’red’可以简写为’r’)

1
2
3
4
# 生成画布,并设置画布的大小
plt.figure(figsize=(6, 6))
# 绘制折线图,只调整线条的样式
plt.plot(x, y, linewidth=3, color='r')

可以看到调整参数 linewidthcolor 后,线条宽度变宽,并且变成红色。

接着调整数据标记点的样式,需要用到的参数是 markermarkerfacecolormarkersize

参数 marker 可以设置数据标记点的形状,有点、圆、加号等,常见为字符串类型,更多的形状

参数 markersizemarkerfacecolor 用来设置数据标记点的大小和填充颜色。markersize 的设置方法与 linewidth 参数相同,而 markerfacecolor 参数的设置方法与 color参数一致。

1
2
3
4
# 生成画布,并设置画布的大小
plt.figure(figsize=(6, 6))
# 绘制折线图,只调整数据标记点的样式
plt.plot(x, y, linewidth=3, color='r', marker='o',markersize=10,markerfacecolor='w')

可以看到调整 markermarkersize 以及 markerfacecolor 之后,数据标记点形状变成圆形,尺寸更大,填充颜色为白色。

调整折线图中图表标题、坐标轴刻度、坐标轴标题的字体样式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 生成画布,并设置画布的大小
plt.figure(figsize=(6, 6))
# 设置 x/y 坐标值
x = order_number.index
y = order_number.values
# 绘制折线图,并调整线条、标记点的样式
plt.plot(x, y, linewidth=3, color='r', marker='o', markerfacecolor='w', markersize=10)
# 设置图表标题名及字体大小
plt.title('各月总订单量趋势图', fontsize=20)
# 设置坐标轴的刻度字体大小
plt.xticks(fontsize=12)
plt.yticks(fontsize=12)
# 设置坐标轴的标题名及字体大小
plt.xlabel('月份', fontsize=15)
plt.ylabel('各月总订单量(百万)', fontsize=15)
# 保存画布
plt.savefig('各月总订单量趋势图.png')
小结

绘制各省各月订单量趋势图

重点调整多条折线图的坐标轴标题、折线以及数据标记点样式,并调整图表标题、坐标轴刻度、坐标轴标题的字体大小。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 调整画布大小
plt.figure(figsize=(6, 6))
# 设置 x/y 坐标值
x = month_order_df.index
y = month_order_df.values
# 绘制折线图,并调整线条、标记点的样式
plt.plot(x, y, linewidth=2, marker='o', markerfacecolor='w', markersize=10)
# 设置图表标题名及字体大小
plt.title('各省各月口罩订单量变化折线图', fontsize=20)
# 设置坐标轴的刻度字体大小
plt.xticks(fontsize=12)
plt.yticks(fontsize=12)
# 设置坐标轴的标题名及字体大小
plt.xlabel('月份', fontsize=15)
plt.ylabel('各省各月口罩订单量(百万)', fontsize=15)
# 添加图例
plt.legend(['其它','广东','江苏','河南','湖北','湖南'])
# 保存画布
plt.savefig('各省各月口罩订单量变化折线图.png')
小结

绘制各月平均单价分布图

“各月平均单价趋势图”和“各月平均单价分布图”拥有相同的数据“单价”以及相同的时间维度“月”,因此 “各月平均单价趋势图”的 x/y 坐标值同样可以用在“各月平均单价柱状图”中。

1
2
3
4
5
6
7
8
# 求得各月平均单价数据,并将其赋值给变量 mask_price
mask_price = mask_data_clean.groupby('月份')['单价'].mean()
# 查看mask_price
mask_price
# 设置 x 坐标值
x = mask_price.index
# 设置 y 坐标值
y = mask_price.values

确定好 x/y 坐标值,接下来调用柱状图绘图函数 plt.bar()开始绘图,与绘图函数 plt.plot()相似,plt.bar()也可以通过调整其中的参数去改变柱子的样式

基于刚才确定的目标,我们重点关注该柱状图的坐标轴标题、数据标签以及柱子样式,并调整图表标题、坐标轴刻度、坐标轴标题的字体大小。

先调整柱子的颜色和宽度,用到的参数分别是 colorwidth。这里的color 和折线图中的color 略有不同,当设置一种颜色时,传入值的类型为字符串;设置多种颜色时,传入值的类型为列表。width 则需要传入(0, 1]区间 (大于 0,小于等于 1) 内的浮点数,数值越大表示柱子的宽度越宽;当 width 的值为 1 时,柱子之间的间隙就为 0。

1
2
3
4
# 生成画布,并设置画布的大小
plt.figure(figsize=(6, 6))
# 绘制柱状图,设置柱子的颜色为绿色,宽度为 0.6
plt.bar(x, height=y, color='g', width=0.6)

可以看到添加了参数 colorwidth 之后,柱子宽度变窄,并且变成绿色。

需要注意,柱的颜色是按照列表中颜色字符串的顺序设置的。

但是这个绿色太深了,只能用“丑”来形容,得想办法优化一下。

参数 alpha 可以设置柱子颜色的透明度,需要传入(0, 1]区间内的浮点数,数值越小,表示柱子颜色越浅;相反,则越深。适当地调整颜色深浅,可以提升视觉舒适度。

综上,我们设置柱子颜色透明度为 60%:alpha=6;调整 1 月份和 6 月份的柱子颜色分别为红色、蓝色,其他柱子依然是绿色:color=['r', 'g', 'g', 'g', 'g', 'b']

1
2
3
4
5
# 生成画布,并设置画布的大小
plt.figure(figsize=(6, 6))

# 绘制柱状图,并调整柱子的颜色和透明度
plt.bar(x, height=y, color=['r', 'g', 'g','g', 'g', 'b'], width=0.6, alpha=0.6)

可以看到,柱子颜色变浅了,而且1 月份和 6 月份的柱子颜色分别变成红色、蓝色。

小结

报告制式

1
2
3
4
5
## 六、数据分析
### 6.1变化趋势
销售额、订单量、单价变化趋势
#### 1. 各月“销售额”:
“销售额”2~3月份急剧上升、3~4月急剧下降,在3月份达到顶峰。
1
2
#### 2.各月“订单量”:
“订单量”表现与“销售额”月表现趋势相同。2~3月份急剧上升、3~4月急下降。在3月份达到顶峰。
1
与疫情前对比,6月份比1月份的订单总量略高(1月份的防护服装订单总量为13852盒,6月份22222盒)
1
2
#### 3. 各月“单价”:
从变化趋势来看,“单价”表现与“销售额”、“订单量”表现趋势相同。2~3月份急剧上升、3~4月急剧下降。在3月份达到顶峰。
1
与疫情前对比,6月份比1月份的防护服装单价更低(1月份的防护服装单价为39元/盒,6月份30元/盒)。
1
2
3
4
5
## 6.2原因分析/内因外因
1. 销售额、订单量、单价波动情况
“销售额”波动:2~3月份急剧上升、3~4月急剧下降。在3月份达到顶峰。
“单价”波动:2~3月份急剧上升、3~4月急剧下降。在3月份达到顶峰。
“订单量”波动:2~3月份急剧上升、3~4月急剧下降。3月份达到顶峰。
1
“各省份订单量”波动:各客户之间的变化趋势相同,并且我们发现湖北省的防护服装订单量显著大于其他省份,湖北省为我们的“大客户”,并且“大客户”的订单量也在大幅降低
1
2. 疫情是在1-3月份呈上升、3-6月份呈下降,疫情与销售额、订单量、单价变化趋势表现一致。与此同时“大客户“群体也同样是疫情期间的影响重灾地区。因此,过往在3月份的明显波动的盈利状况主要与疫情有关系。

图片来自网络,数据与国家卫健委官网一致

https://voice.baidu.com/act/newpneumonia/newpneumonia/?from=osari_aladin_banner

1
3. 与1月(日常情况)对比可知,6月的单价已经降到比较低的水平,订单量相对日常情况略高。由于疫情已经趋于稳定,之后订单量与单价不会再继续同时升高,那么6月已经亏损的情况下,之后的一段时间仍会继续亏损。

撰写数据分析报告

撰写数据分析报告的是为了将分析结果、建议以及其他有价值的信息传递给读者。对于“口罩厂”项目来说,读者是总监,我们要让总监正确地理解结果和建议,并做出有针对性的决策。

数据分析报告的形式

先来看看数据分析报告的形式,其实不限于文档、演示文稿以及表格。但是在不同的场景下,选对形式还是很关键的。

下图是不同形式报告的优劣对比,你可以根据自己的需求选择合适的形式。

数据分析报告的结构

再来看数据分析报告的结构,一般会采用总分总结构,包括:背景、目的、分析思路、分析正文、结论及建议、附录等。

1)背景:阐述进行数据分析的原因、意义,以及其他相关信息,比如公司现阶段的经营情况。

2)目的:这次分析要解决什么问题,达到何种目的。有时会将背景和目的放在一起写。

3)分析思路:用到了什么分析方法,得到的分析框架是什么。

4)分析正文是报告的主体部分,包含所有的数据事实和观点,通过数据图表和文字呈现,一般包括三个

部分:
第一步.数据来源:解释数据的来源,并展示数据的基本情况。
第二步.数据处理:进行了哪些数据处理操作以及处理的结果是什么。
第三步.数据分析:以图文结合的方式展示分析过程和结果,并能证明分析过程合理,分析结果能够应用于实际的工作场景。

5)结论及建议:以综述性文字展现数据分析结果,并结合公司的具体业务或问题给出建议。

6)附录:提供正文中涉及到的,但是未详细阐述的资料,一般包括名词解释、源数据以及分析代码等,为整个分析报告提供补充说明。

项目回顾

1)背景
跟着项目一路走来,你应该再熟悉不过了:公司有一家小型口罩工厂,在今年 6 月底开始处于亏损状态。

2)目标
对历史经营数据进行分析,找到亏损原因,并结合公司实际情况提供对应的解决策略。

3)分析思路
借助公式拆解法,推演出影响口罩厂利润的几个因素以及分析的维度。

4)分析正文

  • 基于分析框架向公司数据部门提交需求,拿到的数据基本符合需求,但也存在一些问题,比如一些数据是脏数据,一些数据则用不到,还有一些数据不是目标格式。
  • 针对上述存在的问题,进行了数据清洗、数据整理、分组聚合以及描述性统计分析等操作。
  • 整理完数据后,根据销售额、订单量、口罩单价、订单来源省份的影响因素以及月的时间维度进行分析,并通过作图查看各个数据的对比和趋势,最终发现数据变化的规律和原因。

除了分析某厂内部的数据,还结合外部环境数据去佐证我们的结论。

5)结论及建议
最后,总结数据变化的规律和原因,并结合口罩厂数据和外部环境数据,从避免亏损和追求盈利两个方向给出建议。

6)附录
在分析报告中没有难以理解的名词,整个过程主要用 Python 对数据进行了分析,所以附上原始数据和分析代码。

报告制式

1
2
3
4
5
6
7
8
9
10
### 七、结论及建议
## 【结论】
结论1:防护服装厂的“销售额”在1-3月份呈上升态势,3-6月份呈下降态势,并且在2-3月份急剧上升,3-4月份急剧下降。“订单量”、“单价”都表现出同样的变化情况。
结论2:疫情是影响防护服装厂销售额、订单量、单价在2-3月份、3-4月份出现急剧上升、急剧下降的现象的原因。
结论3:根据疫情逐渐稳定,防护服装需求下降的情况,可以推断防护服装厂6月份之后还将持续亏损。

## 【建议】
建议1:如果公司不对防护服装厂新投入和改革,防护服装厂会持续亏损,建议尽早对防护服装厂进行转让处理。
建议2:如果公司对防护服装厂新投入和改革,那需要进一步分析产品情况、营销体系等因素对于日常营销的影响,把握住改革重点。
建议3:结合国外的疫情发展,可考虑打开疫情重灾国家的销售渠道,以便保持高单价高销量的营收模式。

总结

  • 标题: 数据分析思路模板
  • 作者: Yiuhang Chan
  • 创建于 : 2020-07-28 09:32:16
  • 更新于 : 2024-02-28 18:49:55
  • 链接: https://www.yiuhangblog.com/2020/07/28/20200728 数据分析报告思路/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论