循環運算

1.     循環比較每行記錄判斷文件是否相同

循環判斷,每次在序列最後添加新的成員。

【例 1】 比較兩個行數相同的文件中有多少行數據完全一致。文件部分數據如下:

ID Predicted_Y Original_Y
10 0.012388464367608093 0.0
11 0.01519899123978988 0.0
13 0.0007920238885061248 0.0
19 0.0012656367468159102 0.0
21 0.009460545997473379 0.0
23 0.024176791871681664 0.0

【SPL腳本】


A B C
1 =file("p_old.csv")[email protected]()
/讀取第一次輸出的文件
2 =file("p_new.csv")[email protected]()
/讀取第二次輸出的文件
3 for A1.len() =cmp(A1(A3),A2(A3)) /循環比較兩個文件同行記錄的數據
4
[email protected]|B3 /把每次比較的結果與 B4 格值合併
5 =B4.count(~==0)
/統計有多少行數據相等

    A5的執行結果如下:

Value
11302

 

2.     循環賦值

對集合的成員進行循環計算並賦值。

【例 2】 在銷售表中,將 2014 年前 10% 的銷售員再給予 5% 的業績獎勵。銷售表部分數據如下:

OrderID Customer SellerId OrderDate Amount
10400 EASTC 1 2014/01/01 3063.0
10401 HANAR 1 2014/01/01 3868.6
10402 ERNSH 8 2014/01/02 2713.5
10403 ERNSH 4 2014/01/03 1005.9
10404 MAGAA 2 2014/01/03 1675.0

【SPL腳本】


A B
1 =connect("db").query("select   * from sales") /連接數據源,讀取銷售表
2 =A1.select(year(OrderDate)==2014) /選出 2014 年數據
3 =A2.groups(SellerId;sum(Amount):Amount) /按銷售員分組彙總當年銷售總額
4 [email protected](Amount).to(A3.len()*0.1) /按銷售額降序排列,取前百分之十
5 =A4.run(Amount*=1.05) /使用函數 A.run(),對前百分之十循環,每人給予銷售額 5% 的獎勵

    A5的執行結果如下:

SellerId Amount
4 150433.185
3 127878.04
1 102756.759
8 87965.346

 

3.     複雜跨行計算

分組統計數據後,對每組分列統計不同的結果,同時跨行計算。

【例 3】根據用戶支付數據明細表,統計各個用戶 2014 年每月應付金額的彙總表。用戶支付數據明細表部分數據如下:

ID customID name amount_payable due_date amount_paid pay_date
112101 C013 CA 12800 2014-02-21 12800 2014-12-19
112102 C013 CA 3500 2014-06-15 3500 2014-12-15
112103 C013 CA 2600 2015-03-21 6900 2015-10-17

要求根據指定年份(如2014),輸出每月應付金額,若無當月數據,則當月應付金額爲上月該值:

name 1 2 3 4 5 6 7 8 9 10 11 12
CA
12800 12800 12800 12800 16300 16300 16300 16300 16300 16300 16300












【SPL腳本】


A B C
1 =file("Payment.txt")[email protected]().select(year(due_date)==2014)
/從文件中導入 2014 年數據
2 =create(name,${12.()[email protected]()}) =A1.group(customID) /A2:生成包含 12 個月的空表。A3:按客戶 ID 分組。
3 for B2 =12.(null) /生成 12 個月的空數據
4
>A3.run(B3(month(due_date))=   amount_payable) /設置相應月份的應付金額。
5
>B3.run(~+=~[-1]) /將空值置爲前一個月的數值,新增應付款項時累加。
6
=A2.record(B2.name|B3) /將記錄插入結果表中。

    A2的執行結果如下:

name 1 2 3 4 5 6 7 8 9 10 11 12
CA
12800 12800 12800 12800 16300 16300 16300 16300 16300 16300 16300












 

4.     最大連續增長天數

在循環計算中,計算某列的連續增長次數。

【例 4】 根據上證指數記錄,求 2019 年收盤價增長的最大連續天數。上證指數表部分數據如下:

Date Open Close Amount
2019/12/31 3036.3858 3050.124 2.27E11
2019/12/30 2998.1689 3040.0239 2.67E11
2019/12/27 3006.8517 3005.0355 2.58E11
2019/12/26 2981.2485 3007.3546 1.96E11
2019/12/25 2980.4276 2981.8805 1.9E11

【SPL腳本】


A B
1 =file("000001.csv")[email protected]() /導入數據文件
2 =A1.select(year(Date)==2019).sort(Date) /選出 2019 年的記錄並按日期排序
3 =n=0,A2.max(if(Close>Close[-1],n+=1,n=0)) /循環收盤價,比較每天的收盤價和前日收盤價,如果當日收盤價更高,則計數加 1,最後選出計數最大值。

    A3的執行結果如下:

Value
6

 

5.     嵌套循環

嵌套使用循環函數計算。

【例 5】 百雞問題,雞翁一值錢五,雞母一值錢三,雞雛三值錢一。百錢買百雞,問雞翁、母、雛各幾?

 

【SPL 腳本】


A B
1 =to(100/5) /可能購買的雞翁數量
2 =to(100/3) /可能購買的雞母數量
3 =33.(~*3) /可能購買的雞雛數量
4 =create(Cock,Hen,Chick) /創建空表用於存放三種雞的數量
5 >A1.run(A2.run(A3.run(if(A1.~+A2.~+A3.~==100   && A1.~*5+A2.~*3+A3.~/3==100,A4.insert(0,A1.~,A2.~,A3.~))))) /分別循環雞翁、雞母、雞雛,當滿足百錢買百雞時,將結果插入到 A4 創建的集合中。其中用到了 ~ 符號代表集合循環的當前成員

    A4的執行結果如下:

Cock Hen Chick
4 18 78
8 11 81
12 4 84

 

6.     循環中調用次數

循環查找文本,並按需要生成結果,循環中需要使用循環次數。

【例 6】 根據文本 1 中的關鍵詞,在文本 2 中查找,希望整理爲輸出結果:

..

【SPL 腳本】


A B
1 =file("file1.txt")[email protected]() /讀取文本 1
2 =file("file2.txt")[email protected]() /讀取文本 2
3 =A1.conj(("Q"+string(#)+"."+~)|A2.select(pos(~,A1.~)).(~.words()(1))) /循環文本 1 中的字符串,在文本 2 中查找,並取第一個英文單詞。A2.select 中用到了 ~ 代表 A2 當前成員,A1.~ 代表 A1 的當前成員。每組搜索結果前拼上 Q+A1 的序號 +A1 當前成員,其中序號通過 #取得。

    A3的執行結果如下:

Member
Q1.   like parks
I
Shelly
Harry
Q2.   went out
Shelly
Q3. go   out
I
Ben
Harry

 

7.     循環時按位置統計臨近數據

循環計算,計算時按位置計算偏移區間內均值。

【例 7】 根據招商銀行的股市交易表,列出 2020 年 1 月 1 日至 10 日每天的 20 日收盤均價。股市交易表部分數據如下:

Date Open Close Amount
2019/12/31 3036.3858 3050.124 2.27E11
2019/12/30 2998.1689 3040.0239 2.67E11
2019/12/27 3006.8517 3005.0355 2.58E11
2019/12/26 2981.2485 3007.3546 1.96E11
2019/12/25 2980.4276 2981.8805 1.9E11

【SPL腳本】


A B
1 =connect("db") /連接數據源
2 =A1.query("select Date, Close from   Stock where Code='600036'order by Date") /選出招商銀行數據並按日期排序
3 [email protected](Date>=date("2020/01/01")   && Date<=date("2020/01/10")) /使用函數 A.pselect() 獲取 2020 年 1 月 1 日到 10 日對應記錄的序號
4 =A2(A3).derive(A2.calc(A3(#),avg(Close[-19:0])):ma20) /使用函數 calc() 循環計算前十日數據的 20 日均值並返回,計算時使用了 Close[-19:0 獲取從過去 19 天到今天的收盤價。

    A4的執行結果如下:

Date Close ma20
2020/01/02 38.88 37.35
2020/01/03 39.4 37.50
2020/01/06 39.24 37.64
2020/01/07 39.15 37.79
2020/01/08 38.41 37.90
2020/01/09 38.9 38.03
2020/01/10 39.04 38.16

 

8.     迭代累加

循環時迭代累加,根據累加值篩選。

【例 8】根據銷售表,統計出 2014 年每個月達到 20 筆訂單所需天數。銷售表部分數據如下:

OrderID Customer SellerId OrderDate Amount
10400 EASTC 1 2014/01/01 3063.0
10401 HANAR 1 2014/01/01 3868.6
10402 ERNSH 8 2014/01/02 2713.5
10403 ERNSH 4 2014/01/03 1005.9
10404 MAGAA 2 2014/01/03 1675.0

【SPL腳本】


A B
1 =connect("db").query("select   * from sales") /連接數據源,讀取銷售表
2 =A1.select(year(OrderDate)==2014) /選出 2014 年數據
3 =A2.sort(OrderDate) /按照訂單日期排序
4 =A3.select(seq(month(OrderDate))==20) /使用函數 seq() 計算每個月份的訂單序號,並選出每個月序號爲 20 的記錄

    A4的執行結果如下:

Month Day
1 20
2 20
3 20
4 18

 

9.     分組計算排名

循環中計算分組中的排名。

【例 9】根據員工收入表,求員工在本部門的收入排名。員工收入表部分數據如下:

ID NAME DEPT SALARY
1 Rebecca R&D 7000
2 Ashley Finance 11000
3 Rachel Sales 9000
4 Emily HR 7000
5 Ashley R&D 16000

【SPL 腳本】


A B
1 =connect("db")   .query("select * from Employee order by DEPT, SALARY DESC") /連接數據源,讀取員工表並按部門和收入排序
2 =A1.derive(rank(SALARY;DEPT):DeptRank) /對有序的部門和收入利用函數 rank() 編號,計算出各部門排名

    A2的執行結果如下:

ID NAME DEPT SALARY DeptRank
2 Ashley Finance 11000 1
32 Andrew Finance 11000 1
230 Hannah Finance 10000 3
24 Chloe Finance 10000 3

 

10.   分組計算緊湊排名

循環計算分組中的緊湊排名。

【例 10】根據成績表,求出一班學生 ID 爲 8 的學生的各科成績在本班的排名。成績表部分數據如下:

CLASS STUDENTID SUBJECT SCORE
Class   one 1 English 84
Class   one 1 Math 77
Class   one 1 PE 69
Class   one 2 English 81
Class   one 2 Math 80

【SPL 腳本】


A B
1 =connect("db")   .query("select * from SCORES where CLASS='Class one'order by SUBJECT,   SCORE DESC") /連接數據源,讀取學生成績表並按學科和成績排序
2 =A1.derive(ranki(SCORE;SUBJECT):Rank) /對有序的學科和成績利用函數 ranki() 計算各科成績的緊湊排名
3 =A2.select(STUDENTID==8) /選出學生 ID 是 8 的學生信息
4 =create(${A3.(SUBJECT)[email protected]()}).record(A3.(Rank)) /利用 A3 選出的結果,整理出各科緊湊排名

    A4的執行結果如下:

English Math PE
10 4 14

 

11.   迭代求和

循環計算迭代求和的結果。

【例 11】根據上證指數表,計算 2019 年每個交易日的全年累計成交金額。上證指數表部分數據如下:

Date Open Close Amount
2019/12/31 3036.3858 3050.124 2.27E11
2019/12/30 2998.1689 3040.0239 2.67E11
2019/12/27 3006.8517 3005.0355 2.58E11
2019/12/26 2981.2485 3007.3546 1.96E11
2019/12/25 2980.4276 2981.8805 1.9E11

【SPL 腳本】


A B
1 =file("000001.csv")[email protected]() /導入數據文件
2 =A1.select(year(Date)==2019).sort(Date) /選出 2019 年的記錄並按日期排序
3 =A2.derive(cum(Amount):CUM) /使用 cum() 函數計算累計成交金額

    A3的執行結果如下:

Date Open Close Amount CUM
2019/01/02 2497.8805 2465.291 9.759E10 9.759E10
2019/01/03 2461.7829 2464.3628 1.07E11 2.046E11
2019/01/04 2446.0193 2514.8682 1.39E11 3.436E11
2019/01/07 2528.6987 2533.0887 1.46E11 4.896E11
2019/01/08 2530.3001 2526.4622 1.23E11 6.126E11

 

12.   自定義迭代計算

循環中使用迭代計算,自行設置迭代中的計算表達式和終止條件。

【例 12】根據銷售表數據,統計 2014 年第一季度到哪一天完成了銷售總額 15 萬的季度目標。銷售表部分數據如下:

OrderID Customer SellerId OrderDate Amount
10400 EASTC 1 2014/01/01 3063.0
10401 HANAR 1 2014/01/01 3868.6
10402 ERNSH 8 2014/01/02 2713.5
10403 ERNSH 4 2014/01/03 1005.9
10404 MAGAA 2 2014/01/03 1675.0

【SPL腳本】


A B
1 =connect("db").query("select   * from sales") /連接數據源,讀取銷售表
2 =A1.select(year(OrderDate)==2014) /選出 2014 年數據
3 =A2.iterate((@+=Amount,   ~~=OrderDate),0,@>150000) /使用函數 iterate() 迭代計算,初始值爲 0。將銷售額累加到當前格,直到超過 15 萬終止。函數返回訂單日期。

    A3的執行結果如下:

Value
2014/03/25

 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章