第 2 章 一个简单的数据分析

 

第 1 章 准备工作

2.1 数据介绍

使用 Excel 打开某公司的销售数据表 saledata.csv 如下:

imagepng

第一行加粗的数据通常为列的描述信息,它不是数据本身,通常我们作为列名来称呼它,不过软件界面中沿用了数据库的术语,列被称为字段(Field),而数据行称为记录(Record)。从第二行开始才是数据本身。

saledata.csv 文件中列名的含义如下:

列名 含义
orderID 订单 ID,取值为自然数列,和数据行号一致
orderDate 订单日期
sales 销售
customer 客户
product 产品
quantity 订单数量
price 订单价格
discount 订单折扣
paymentDate 付款日期
feedBack 客户反馈

2.2 选出 2024 年的所有销售数据

第一步:打开 saledata.csv 文件中的数据

SPL WIN 启动后,在如图所示数据文件列表中,选中红框所示 saledata.csv 文件:

imagepng

鼠标双击文件,内容面板区会增加一个名为 saledata本书中红色斜体表示可以直接在表达式中引用的变量或者函数名)的标签页,并在顶部显示了打开表的总行数:

imagepng

可以看到列 quantityprice 以及 discount 不同于前面各列,分别显示为蓝色和粉色。这是因为这些数据列的内容为数值,SPL WIN 中,使用蓝色显示整数,粉色显示浮点数,用以更直观地展示不同类型的数据。

知识点: SPL WIN 中显示在内容面板区标签页中的数据表称为序表,区别于数据库中的数据表,序表的数据行是有序的,可以通过序号直接访问某一行记录。比如在手写命令区输入 saledata(3),执行后将返回 saledata 表中的第三行。

第二步:尝试选出 2024 年下单的数据:
单击图示工具栏中过滤本书中红色正体表示当前文字来源于界面,可为界面中控件名称,或者在界面中输入的文字)图标:

imagepng

在弹出的过滤窗口中,如图输入year(orderDate)==2024表达式,其中 year 函数表示取出订单日期的年份:

imagepng

界面默认赋予了 filter 作为缺省表名,这个名字可以修改为有业务意义的表名,但后面的源表 saledata 不可修改,表示当前计算基于源表 saledata 。按 OK 确认计算后,计算结果将产生一个名为 filter 的新表,如果表名跟源表名相同,则计算结果会覆盖掉源表。

不过此时单击 OK 后,结果却提示:

imagepng

意思为错误的参数类型,原来我们直接打开的表,本该为日期类型的 orderDate 因为格式与程序环境配置不一致,没能正确解析,仍读取为字符类型。

解决方法 1:修改表达式为 year(date(orderDate,”yyyy/MM/dd”))==2024,通过 date 函数指定日期格式后,将 orderDate 转换为日期类型:

imagepng

知识点:date 函数用于将字符串、整数或长整数转换成日期型数据。其详细用法请参考 https://d.raqsoft.com.cn:6443/esproc/func/date.html

再次单击 OK 后,产生了只包含 2024 年订单的 filter 表:

imagepng

虽然使用日期转换函数,能实时转换日期类型,但如果每次计算都要加上这个转换,仍然比较麻烦。

解决方法 2:可以在打开文件时,便指定好正确的解析格式,这样打开的文件,数据类型会先转换好,后续计算时不再需要转换表达式。步骤为选中文件后,单击图示浏览按钮:

imagepng

在打开的文件配置界面中,如图设置好订单日期的数据类型(Type)和解析格式(Format):

imagepng

OK打开后,订单日期就会自动转换为日期类型。但这种方式还是有些许麻烦,毕竟要分析的数据,日期格式大多是相同的,如果每次打开文件前都要设置一下,仍然有点繁琐。

解决方法 3:单击图示选项按钮:

imagepng

在选项窗口中,根据当前文件中日期的格式,将日期解析格式设为yyyy/MM/dd

imagepng

通过选项设置后,所有双击打开的文本数据,只要数据中的日期格式跟选项设置一致,都能解析为日期类型。需要注意的是,SPL WIN 中选项的配置文件,是直接沿用当前环境中 SPL 的配置文件,故有部分选项在 SPL WIN 中没有意义,在本书中不必关注。

2.3 选出 2024 年销售额最大的三个订单

需用计算列算出订单销售额,使用公式quantity*price*discount作为计算列表达式算出销售额amount

第一步:2.2 节中,filter 已经是过滤后的 2024 年的全部数据,在该表中,单击图示计算列按钮:

imagepng

界面弹出计算列的编辑窗口,点击图示计算列后的加号后,在增加的表达式行如图设置计算列的表达式以及该计算列的别名:

imagepng

单击OK后,可以看到表 filter 的最后一列,增加了销售额 amount

imagepng

第二步:算出了每笔订单的销售额后,只需按 amount 列降序排列,取前三便可得到最大的三笔订单,将光标落在 amount 列,单击图示排序图标:

imagepng

打开的排序窗口默认按当前列设置为升序排列,我们需要降序,故去掉升序复选框:

imagepng

单击OK后,得到了按 amount 降序排列的结果:

imagepng

第三步:只取销售额的前三名,仍然可以用过滤窗口实现,单击过滤图标,输入过滤表达式#<=3

imagepng

单击OK后,得到最大的三笔订单:

imagepng

知识点:序表的行号从序号 1 开始,在表达式中,使用符号#来引用每条记录的序号。

2.4 计算 2024 年的总销售额、单笔最大订单额、订单个数

2.3 节 filter 表中,已经算好了每一笔订单的销售额 amount,选中内容面板区 filter 表。

解决方法 1:对 filter 进行分组汇总。将光标落在 amount 列,单击图示分组图标:

imagepng

在弹出的分组窗口中,窗口默认添加了 amount 分组,这能方便大多数分组运算。但此处只求总销售额,以及所有销售额中的最大额,故不需要指定分组表达式,也即将整个 filter 表作为一组数据,如图单击减号,删除当前分组:

imagepng

删掉分组字段的表达式后,依次按图示顺序单击标签页的聚合页面(1),选中源字段 amount(2),单击加号增加一行聚合表达式(3),调整当前聚合表达式的聚合函数(4),然后重复(3)和(4),编辑出图示销售总额,最大销售额,以及订单计数:

imagepng

单击OK后,便计算出了所需结果:

imagepng

数据分组后,大多情形下,人们更加关注每组的某个指标值。计算出指标值后,分组的明细记录便被丢弃了,看起来是将明细记录聚合成了一个值,这也是聚合值名称的由来。SPL WIN 支持所有常见的聚合运算,比如, sum 为求汇总值, count 为计数,max 为最大值,min 为最小值,avg 为平均值,icount 为去掉重复值后的计数。

知识点:SPL WIN 中聚合函数还支持 top 函数,它能根据计算条件,返回更精细控制的一个或者多个值。具体使用方法请参考:https://d.raqsoft.com.cn:6443/esproc/func/top1.html

解决方法 2:当前题意,不使用界面分组,在手写命令区直接执行表达式更加简便,如图步骤,输入计算总额表达式filter.sum(amount),然后单击执行命令按钮,便能得到销售总额:

imagepng

类似地,可以算出最大订单金额值:

imagepng

至于订单个数,其实 filter 表的记录数已经是答案。

2.5 找出 2024 年第一笔付款的订单、最后一笔付款的订单

很自然想到只要按付款日期 paymentDate 排序后,即可找出第一笔付款以及最后付款的订单。但排序法,其实不是最合适的解法,数据量不大时,该方法还能凑合。如果数据量很大,排序过程很浪费时间,这种方法便不可忍受了。

SPL 有直接定位函数,使用 maxp 便能快速找出最后付款订单,大大提高工作效率。
在手写命令区执行表达式filter.maxp(paymentDate),然后按执行按钮:

imagepng

可以看到使用 maxp 函数,能更方便算出最后付款的订单。类似地,使用 minp 函数,即可算出最早付款的订单。

使用 maxp 函数找最后付款订单时,缺省情形下,找到一行数据后便返回了。其实该表中还存在同时付款的其他订单。那要找出所有数据行时,需要用到函数选项。在手写命令区执行filter.maxp@a(paymentDate),这才找出了所有的最后付款订单:

imagepng

知识点:SPL 函数的选项写法,实现了一个函数多种用途。使用函数选项时,需在函数名后跟上 @ 连接符。上例中maxp@a表示返回所有相同条件的数据行。 maxp 函数的详细用法请参考:https://d.raqsoft.com.cn:6443/esproc/func/amaxpx.html#A_maxp

使用 maxp 函数,可以找出符合最大条件的数据行,但生活中还有很多常见的场景,不止找最大的,还想要第二大的,比如学生成绩排名,往往需要颁奖前三名。此时 maxp 就没法实现了。这时需要用到 2.4 节介绍过的 top 函数, top 函数中,可以返回任意排名的数据行。

2.6 统计 2025 年 5 月 1 日以后下单的客户数和付款的客户数(去重)

解决方法 1:仍然可以使用界面可视步骤,先过滤出指定时间以后的行,再按客户分组统计结果。

第一步:选中 saledata 表,再用过滤表达式orderDate>date("2025/05/01")选出 2025 年 5 月 1 日以后的数据行:

imagepng

单击OK后,得到过滤后数据表 filter

imagepng

第二步:按照 customer 分组,分组字段即为 customer ,本题不关心组内数据汇总,就不需要设置聚合表达式了,但每组要保留一行数据,选中返回每组的首行

imagepng

OK后,便可得到所有的客户数目 897:

imagepng

第三步:为了计算付款的客户数,则仍需在 filter 上,继续选出付款过(paymentDate!=null)的数据行:

imagepng

过滤后,同样分组,计算出付款过的客户数为 405:

imagepng

解决方法 2:使用分组的方式去重分组名称再统计,对分组计算来说,有点大材小用了。类似于 2.4 节使用 maxp 函数,去重也有直接使用的函数 id 。在手写命令区输入:filter.id(customer).count()。执行后得到客户数:

imagepng

知识点id 函数用于从序表中获取去掉重复后的值,更多参数以及选项详情,请参考:https://d.raqsoft.com.cn:6443/esproc/func/aid.html