我在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的建议
解决你的最后一点,"如何改变我的心态,正确编程?":
您需要利用(/),扫描(\)和.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"类型循环
至于嵌套循环,我发现有用的是创建交叉列表。例如
`对于 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 语法。如果您能知道您想要什么输出,那么可以提供帮助。