KDB/Q:如何循环没有循环?

Mar*_*ene 8 kdb

我在kdb数据库上学习q.我担心q中没有循环这一事实.我需要编写一个算法,我会在像C这样的详细程序中用几个嵌套的for循环编写.但是在q中我被不能循环的事实所困扰.

只是给出一个具体的例子(其中一个),我有这个简单的向量(列表):

q)closures
price
-----
18.54
18.53
18.53
18.52
18.57
18.9 
18.9 
18.77
18.59
18.51
18.37
Run Code Online (Sandbox Code Playgroud)

我需要一个向3by3这些条目组合的向量,具有叠加,如(使用R语法):闭包[0:2],闭包[1:3],闭包[2:4],闭包[3:5] ......我能怎么做?

一般来说,我如何改变自己的心态,正确编程?

非常感谢您对Marco的建议

ter*_*nch 8

解决你的最后一点,"如何改变我的心态,正确编程?":

您需要利用(/),扫描(\)和.zs而不是使用循环.

例如,您的问题可以通过以下方式解决:(请注意,这些问题实际上并不是针对您的特定问题的最佳解决方案 - 索引是更好的方法 - 但是下面的这些解决方案应该有助于解决问题)

price:18.54 18.53 18.53 18.52 18.57 18.9 18.9 18.77 18.59 18.51 18.37

q)3#'{1_x}\[8;price]
18.54 18.53 18.53
18.53 18.53 18.52
18.53 18.52 18.57
18.52 18.57 18.9
18.57 18.9  18.9
18.9  18.9  18.77
18.9  18.77 18.59
18.77 18.59 18.51
18.59 18.51 18.37
Run Code Online (Sandbox Code Playgroud)

即迭代列表,每次切断一次,每次迭代前3次

或类似的

q)3#'{1 rotate x}\[8;price]
18.54 18.53 18.53
18.53 18.53 18.52
18.53 18.52 18.57
18.52 18.57 18.9
18.57 18.9  18.9
18.9  18.9  18.77
18.9  18.77 18.59
18.77 18.59 18.51
18.59 18.51 18.37
Run Code Online (Sandbox Code Playgroud)

即旋转1次,每次旋转前3次

使用.zs方法

q){$[2<count x;enlist[3#x],.z.s 1_x;()]}[price]
18.54 18.53 18.53
18.53 18.53 18.52
18.53 18.52 18.57
18.52 18.57 18.9
18.57 18.9  18.9
18.9  18.9  18.77
18.9  18.77 18.59
18.77 18.59 18.51
18.59 18.51 18.37
Run Code Online (Sandbox Code Playgroud)

即如果剩下至少3个元素,则先取3,然后砍掉第一个项目,并将相同的函数重新应用于缩短的列表.

在这个例子中使用over(/)会很复杂,但总的来说,替换"while"类型的构造是有用的

i:0
a:0;
while[i<10;i+:1;a+:10] 
Run Code Online (Sandbox Code Playgroud)

使用更好

q){x+10}/[10;0]
100
Run Code Online (Sandbox Code Playgroud)

即添加10次,十次,起始(种子)值为零.

b:();  
while[not 18~last b;b,:1?20]      
Run Code Online (Sandbox Code Playgroud)

即保持在1到20之间追加随机数,直到你达到18,然后停止.

使用更好

q){x,1?20}/[{not 18~last x};()]
1 2 16 5 8 18
Run Code Online (Sandbox Code Playgroud)

即附加一个介于1和20之间的随机数,只要检查函数返回true就会迭代,以()作为种子值开始

还有许多其他选项可供使用扫描和结束,具体取决于您迭代的函数是monadic/diadic等.

作为一个广泛的概括:可以使用"function each i"在q中实现"for i = 1:10"类型循环,可以使用"function/[numOfTimes; seed]"在q中实现"do"类型循环,使用"function/[booleanCheckFunction; seed]"可以在q中实现"while"类型循环


Nav*_*rma 2

至于嵌套循环,我发现有用的是创建交叉列表。例如

`对于 i=1:10

 for j=1:20
    for k=1:30
      f(i, j, k)
Run Code Online (Sandbox Code Playgroud)

`

在q中你可以

il: 1 _til 11
jl: 1_til 21
kl: 1_til 31
lst: il cross jl cross kl
raze g(x) each til count ls
Run Code Online (Sandbox Code Playgroud)

其中 g 定义为

g: {[i]
itr: first lst[i];
jtr: first 1_lst[i];
ktr: last lst[i];

f(itr, jtr, ktr)
}
Run Code Online (Sandbox Code Playgroud)

希望这能澄清。至于闭包部分不知道 R 语法。如果您能知道您想要什么输出,那么可以提供帮助。