(q/kdb +)使用先前行的结果更新行

Jms*_*Jms 0 kdb

使用表格

t:([]c1: 3 4 7 2 4.0;c2: 2 8 10 1 9.0;c3:5 8 13 2 11.0)

c1  c2  c3
3   2   5
4   8   8
7   10  13
2   1   2
4   9   11
Run Code Online (Sandbox Code Playgroud)

我需要更新3个新列(c1M,c2M,c3M),其中:

  • 第一行:

    • c1M:avg(c1,c2,c3)
    • c2M:avg(c1,c2)
    • c3M:c3
  • 其他行:

    • c1M:avg(c1,c2,c3)
    • c2M:avg(prev c1M,prev c2M)
    • c3M:max(c3,c1M,c2M)

我可以用第一排做

t:update c1M:avg(c1,c2,c3),c2M:avg(c1,c2),c3M:c3 from t where i=0

c1  c2  c3  c1M c2M c3M
3   2   5   3.3 2.5 5
4   8   8   0n  0n  0N
7   10  13  0n  0n  0N
2   1   2   0n  0n  0N
4   9   11  0n  0n  0N
Run Code Online (Sandbox Code Playgroud)

不知道如何坚持下去.我尝试过类似的东西:

update c1M:avg(c1;c2;c3),c2M:avg(prev c1M;prev c2M),c3M:c3|c1M|c2M from t where i>0
Run Code Online (Sandbox Code Playgroud)

但没有运气.

此示例的结果应为:

c1  c2  c3  c1M c2M c3M
3   2   5   3.3 2.5 5.0
4   8   8   6.7 2.9 8.0
7   10  13  10  4.8 13.0
2   1   2   1.7 7.4 7.4
4   9   11  8.0 4.5 11.0
Run Code Online (Sandbox Code Playgroud)

有人能帮我吗?

R. *_*ler 5

KDB +在矢量计算上比在迭代时快得多.因此,可能更快的方法是使用副词在c2M列上进行迭代,因为它是唯一需要列中前一个值的列.我想你可能正在寻找的是:

update c3M:c3 from (update c3M:max(c3;c1M;c2M) from update c2M:{avg x,y}\[first 
c2;first[c1],1_prev c1M] from update c1M:avg(c1;c2;c3) from t) where i=0
Run Code Online (Sandbox Code Playgroud)

这比在整个表上迭代和执行计算运行得更快,如下所示:

q)\ts:1000 ({update c3M:max(c3;c1M;c2M),c2M:c2M^avg(prev c1M;prev 
c2M),c1M:c1M^avg(c1;c2;c3) from x}/)[update 
c1M:avg(c1,c2,c3),c2M:avg(c1,c2),c3M:c3 from t where i=0]
53 7568

q)\ts:1000 update c3M:c3 from (update c3M:max(c3;c1M;c2M) from update c2M: 
{avg x,y}\[first c2;first[c1],1_prev c1M] from update c1M:avg(c1;c2;c3) from 
t) where i=0
11 6896
Run Code Online (Sandbox Code Playgroud)