ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

结构化数据上用序号访问成员的问题

2020-10-15 13:50:39  阅读:295  来源: 互联网

标签:10 结构化 12 Date A2 上用 序号 2019


序号访问是指通过序号(索引下标)来访问有序集合的成员。序号访问除了按单个序号访问集合成员,还有按多个序号同时取多个成员的需求。除此以外,还有用倒数的序号访问成员,按固定跨度访问成员等等。如何简单快捷的实现这些序号访问需求?这里将为你全程剖析,并提供 esProc SPL 示例代码。

1. 单序号访问

我们可以按照单个序号,从数据表中获取一条记录。

【例 1】 求 2019 年上证指数第一个交易日和最后一个交易日的交易信息。部分数据如下:

DateOpenCloseAmount
2019/12/313036.38583050.1242.27E11
2019/12/302998.16893040.02392.67E11
2019/12/273006.85173005.03552.58E11
2019/12/262981.24853007.35461.96E11
2019/12/252980.42762981.88051.9E11

【SPL脚本】


AB
1=file("000001.csv").import@ct()/导入数据文件
2=A1.select(year(Date)==2019).sort(Date)/选出 2019 年的记录并按日期排序
3=A2(1)|A2.m(-1)/取出上证指数第一个和最后一个交易日的信息。使用了函数 A2(1) 取序表第一条记录,函数 A2.m(-1) 取序表的倒数第一条记录。

A3的执行结果如下:

DateOpenCloseAmount
2019/01/022497.88052465.2919.76E10
2019/12/313036.38583050.1242.27E11

 

有时候我们需要获取指定位置成员的序号,尤其是倒着取集合成员的序号。比如 2019 年上证指数的记录按时间排序后,倒数第二个交易日的序号是多少?这时我们希望通过参数 -2 来获取真实的序号。

【例 2】 以员工表为例,统计 [California, Texas, New York, Florida] 各州的平均工资,其他地区的员工存放到新组统计。部分数据如下:

IDNAMESTATESALARY
1RebeccaCalifornia7000
2AshleyNew   York11000
3RachelNew   Mexico9000
4EmilyTexas7000
5AshleyTexas16000

【SPL脚本】


AB
1=connect("db")/连接数据库
2=A1.query("select * from   EMPLOYEE")/查询雇员表
3[California,Texas,New York,Florida]/创建地区集合
4=A2.align@an(A3,STATE)/雇员表按地区对位分组,@a 选项每组返回所有匹配成员,@n 选项不匹配成员存放到新组。
5=A4.new(if   (#>A3.p(-1),"Other",STATE):STATE,~.avg(SALARY):AvgSalary)/统计每组的平均工资,产生新序表。使用函数 A.p(-1) 获取最后一个成员的序号,把最后一组的地区更名为 Other。

A5的执行结果如下:

STATESALARY
California7700.0
Texas7592.59
New   York7677.77
Florida7145.16
Other7308.1

 

2. 多序号访问

前面介绍了如何使用单个序号访问集合成员,有时候需要根据多个序号获取多条记录。例如对于某年按月份有序的销售记录表,使用序号集合 [4,5,6] 可以访问第二季度的数据。对于一周的值班表,使用序号集合 [1,7] 可以访问周末的值班记录。

【例 3】 有一个记录日常考勤信息的表,如下图:

Per_Codein_outDateTimeType
111026312013-10-1109:17:14In
111026362013-10-1111:37:00Break
111026352013-10-1111:38:21Return
111026302013-10-1111:43:21NULL
111026362013-10-1113:21:30Break
111026352013-10-1114:25:58Return
111026322013-10-1118:28:55Out

每七条数据为一组,想要转换成如下结果:

Per_CodeDateInOutBreakReturn
11102632013-10-119:17:1418:28:5511:37:0011:38:21
11102632013-10-119:17:1418:28:5513:21:3014:25:58

【SPL脚本】


AB
1=connect("db")/连接数据库
2=A1.query("select * from DailyTime   order by Per_Code,Date,Time")/查询数据,并按人员编号、日期和时间排序
3=A2.group(Per_Code,Date)/按人员编号和日期分组
4=create(Per_Code,Date,In,Out,Break,Return)/创建一个存放最后结果的空表
5=A3.(~([1,7,2,3,1,7,5,6]))/对每个组,使用函数 A([1,7,2,3,1,7,5,6]) 依次取出记录,这就是有序的全天记录。
6=A5.conj([~.Per_Code,~.Date]|~.(Time).m([1,2,3,4])|[~.Per_Code,~.Date]|~.(Time).m([5,6,7,8]))/将每条记录的数据全部整理到一个集合中。其中用到了函数 A.m() 访问多个成员。
7>A4.record(A6)/将数据添加到 A4 创建的表中。

A4的执行结果如下:

Per_CodeDateInOutBreakReturn
11102632013-10-119:17:1418:28:5511:37:0011:38:21
11102632013-10-119:17:1418:28:5513:21:3014:25:58

 

类似的,我们也可以从后向前访问多个成员。

【例 5】 求上证指数 2019 年最后 10 个交易日收盘价较前日的涨幅。部分数据如下:

DateOpenCloseAmount
2019/12/313036.38583050.1242.27E11
2019/12/302998.16893040.02392.67E11
2019/12/273006.85173005.03552.58E11
2019/12/262981.24853007.35461.96E11
2019/12/252980.42762981.88051.9E11

【SPL脚本】


AB
1=file("000001.csv").import@ct()/导入数据文件
2=A1.select(year(Date)==2019).sort(Date)/选出 2019 年的记录并按日期排序
3=A2.p(to(-10,-1))/使用函数 A.p() 返回最后 10 个成员的序号
4=A3.new(A2(~).Date:Date,   string(A2(~).Close/A2(~-1).Close-1, "0.000%" ):Increase)/循环计算每个交易日收盘价与前一个交易日的涨幅

A4的执行结果如下:

DateIncrease
2019/12/18-0.178%
2019/12/190.001%
2019/12/20-0.402%
2019/12/23-1.404%
2019/12/240.673%

 

3. 固定跨度访问

固定跨度访问是指按指定的起始序号和固定的跨度访问成员。例如从数据表中抽样,每 10 条记录选出一条,可以从第一条开始取,每 10 条取一次。又比如从 1 到 100 的自然数中,选出所有 3 的倍数,可以从第 3 个数字开始,每 3 个数字取 1 个。

【例 6】 求 100 以内质数。

【SPL 脚本】


AB
1=to(100)/创建 1 到 100 集合
2=to(2,10)/创建 2 到 10 集合
3=A2.(A1.step(~,~*2))/使用了函数 A1.step(~,~*2),针对 A2 中每一个成员,求出它在 100 以内的 n 倍数 (n>1)
4=A1.to(2,)\A3.conj()除去 1 和所有 100 以内的合数即为 100 以内的质数,其中 A3.conj() 求出 100 以内的合数

A4的执行结果如下:

Member
2
3
5
7
11
13
17
19


标签:10,结构化,12,Date,A2,上用,序号,2019
来源: https://blog.51cto.com/12749034/2541876

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有