SPL:按序号对齐的分组和排序

   有时候我们会按照序号顺序将数据进行分组和排序,把序号相同的成员分到同一组。比如按 1 到 12 月的顺序统计上一年每个月的销售总额,按照周一到周日的顺序统计某网站的访问人次等等。

   这种按指定基准对齐的分组运算,我们统称为对齐分组。按序号对齐分组是对齐分组的一种特例,其基准集合是从 1 开始的整数列。对齐分组可能会有空组,也可能有成员未分配到任何一个组中。

1.   按序号顺序排序

   按指定的序号顺序将数据排序,每组保留最多一个匹配成员。适用于我们希望按照指定顺序查看或者使用数据的情况。

【例 1】 根据每日销售表,按每周一到周日的顺序查询销售记录。部分数据如下:

Week Day Amount
5 Sunday 1101.2
5 Saturday 538.6
5 Friday 2142.4
5 Thursday 1456.0
5 Wednesday 48.0
5 Tuesday 1376.0
5 Monday 676.0
4 Sunday 448.0
4 Saturday 4031.0
4 Friday 364.8

 

   在 SPL 中函数 A.align(n,y) 用于对齐分组 ,直接划分为 n 个组(从 1 到 n),并根据分组表达式 y 直接计算出每个成员对应的组号。默认每组保留最多一个匹配成员。

   SPL脚本如下:


A
1 =T("DailySales.csv")
2 ["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"]
3 =A1.group(Week; ~.align(7,A2.pos(Day)):WeekSales)
4 =A3.conj(WeekSales)
5 =A4.select(~)

A1:查询每日销售表。

A2:定义从周一到周日的序列。

A3:销售数据按周分组时,使用函数 A.align(n,y) 将每周的销售记录,按照A2定义好的顺序进行对齐。这里值得注意的是,对齐分组可能会有空组。例如当第二周的周五和周六没有销售记录时,仍然会产生每周 7 个小组:

Week
[2,Monday,1194.0]
[2,Tuesday,1622.4]
[2,Wednesday,319.2]
[2,Thursday,802.0]
(null)
(null)
[2,Sunday,2123.2]

 

A4:将每周排序后的销售记录合并。

A5:从结果集中选出非空的记录。

   其中A5的执行结果如下:

Week Day Amount
1 Monday 3063.0
1 Tuesday 3868.6
1 Wednesday 2713.5
1 Thursday 1005.9
1 Friday 1675.0
1 Saturday 400.0
1 Sunday 2018.2
2 Monday 1194.0
2 Tuesday 1622.4
2 Wednesday 319.2

 

2.   每组保留所有匹配成员

   按指定的序号顺序将数据分组,每组保留所有匹配成员。适用于关心每组的成员信息,或者需要用这些成员记录继续进行统计的场景。

【例 2】 根据销售表,顺序列出 2014 年每个月的销售总额。销售表部分数据如下:

ID CustomerID OrderDate Amount
10248 VINET 2013/07/04 2440
10249 TOMSP 2013/07/05 1863.4
10250 HANAR 2013/07/08 1813.0
10251 VICTE 2013/07/08 670.8
10252 SUPRD 2013/07/09 3730.0

 

    在 SPL 中函数 A.align(n,y) 的选项 @a,用于在对齐分组时每组保留所有匹配成员。

    SPL脚本如下:


A
1 =T("Sales.csv")
2 =A1.select(year(ORDERDATE)==2014)
3 =A2.align@a(12,month(ORDERDATE))
4 =A3.new(#:Month,~.sum(AMOUNT):AMOUNT)

A1:查询销售表。

A2:从销售表中选出 2014 年的记录。

A3:使用函数 A.align@a(n,y),将订单表的月份按照 1 到 12 的顺序分为 12 组,选项 @a 每组保留所有匹配成员。

A4:统计每个月的销售总额。

   其中A4的执行结果如下:

Month Amount
1 66692.8
2 52207.2
3 39979.9
4 60699.39

 

3.   按序号重复性分组

   有时候每条记录计算出的分组序号是多个,我们希望将记录按照序号数列重复性的分配到多个组中。

【例 3】 根据发帖记录表,按标签将帖子分组,并统计各个标签出现频数。发帖记录表部分数据如下:

ID Title Author Label
1 Easy analysis of Excel 2 Excel,ETL,Import,Export
2 Early commute: Easy to pivot excel 3 Excel,Pivot,Python
3 Initial experience of SPL 1 Basics,Introduction
4 Talking about set and reference 4 Set,Reference,Dispersed,SQL
5 Early commute: Better weapon than Python 4 Python,Contrast,Install

 

   在 SPL 中函数 A.align(n,y) 的选项 @r,用于在对齐分组时按序号重复性分组。

    SPL脚本如下:


A
1 =T("PostRecord.txt")
2 =A1.conj(Label.split(",")).id()
3 =A1.align@ar(A2.len(),A2.pos(Label.split(",")))
4 =A3.new(A2(#):Label,~.count():Count).sort@z(Count)

A1:查询发帖记录表。

A2:将标签按逗号分隔后合并到一个序列,获得没有重复值的全部标签。

A3:使用函数 A.align@r(n,y) 的,按照每个帖子的标签在全部标签中的定位分组,选项 @r。

A4:统计每个标签的帖子数量,按降序排列。

    其中A4的执行结果如下:

Label Count
SPL 7
Excel 6
Basics 5

DailySales.csv

Sales.csv

PostRecord.txt