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