(q/kdb+) 使用前几行的结果更新行
(q/kdb+) Update rows using results from previous rows
使用table
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
我需要更新 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
不确定如何继续艰难。我试过类似的东西:
update c1M:avg(c1;c2;c3),c2M:avg(prev c1M;prev c2M),c3M:c3|c1M|c2M from t where i>0
但运气不好。
这个例子的结果应该是:
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
有人可以帮助我吗?
我想你在这里找的东西已经结束了:
http://code.kx.com/q/ref/adverbs/#over
它将遍历 table
的每一行
q)({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]
c1 c2 c3 c1M c2M c3M
--------------------
3 2 5 3.3 2.5 5
4 8 8 6.7 2.9 8
7 10 13 10 4.8 13
2 1 2 1.7 7.4 7.4
4 9 11 8 4.5 11
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
这比在整个 table 上迭代和执行计算运行得更快,如下所示:
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
q) nt:update c1m:avg(c1;c2;c3) from t
q) nt:update c2m:-1_({avg x,y}\[avg[c1[0],c2[0]],c1m]) from nt
q) nt:update c3m:(c3[0],1_max(c3;c1m;c2m)) from nt
另一种方法,可能不是最快的但代码占用空间更小
q){y,`c1M`c2M`c3M!a,max y[`c3],a:(avg y;avg y[`c1`c2]^x`c1M`c2M)}\[t@-1;t]
c1 c2 c3 c1M c2M c3M
-----------------------------------
3 2 5 3.333333 2.5 5
4 8 8 6.666667 2.916667 8
7 10 13 10 4.791667 13
2 1 2 1.666667 7.395833 7.395833
4 9 11 8 4.53125 11
使用table
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
我需要更新 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
不确定如何继续艰难。我试过类似的东西:
update c1M:avg(c1;c2;c3),c2M:avg(prev c1M;prev c2M),c3M:c3|c1M|c2M from t where i>0
但运气不好。
这个例子的结果应该是:
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
有人可以帮助我吗?
我想你在这里找的东西已经结束了: http://code.kx.com/q/ref/adverbs/#over
它将遍历 table
的每一行q)({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]
c1 c2 c3 c1M c2M c3M
--------------------
3 2 5 3.3 2.5 5
4 8 8 6.7 2.9 8
7 10 13 10 4.8 13
2 1 2 1.7 7.4 7.4
4 9 11 8 4.5 11
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
这比在整个 table 上迭代和执行计算运行得更快,如下所示:
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
q) nt:update c1m:avg(c1;c2;c3) from t
q) nt:update c2m:-1_({avg x,y}\[avg[c1[0],c2[0]],c1m]) from nt
q) nt:update c3m:(c3[0],1_max(c3;c1m;c2m)) from nt
另一种方法,可能不是最快的但代码占用空间更小
q){y,`c1M`c2M`c3M!a,max y[`c3],a:(avg y;avg y[`c1`c2]^x`c1M`c2M)}\[t@-1;t]
c1 c2 c3 c1M c2M c3M
-----------------------------------
3 2 5 3.333333 2.5 5
4 8 8 6.666667 2.916667 8
7 10 13 10 4.791667 13
2 1 2 1.666667 7.395833 7.395833
4 9 11 8 4.53125 11