2017-06-13 57 views
1

如何根据其他向量的值有效且简洁地切换公式?[KDB +/Q]:有条件的嵌套向量

kx documentation,有可能

已经不仅仅是一个真/假的选择,例如更MATCH1/MATCH2/MATCH3 /其他映射RESULT1/RESULT2/result3 /默认

数据:

q)t:([]a:til 5;b:10+til 5;c:100+til 5;d:1000+til 5;g:`I`B`I`U`B) 
a b c d g 
--------------- 
0 10 100 1000 I 
1 11 101 1001 B 
2 12 102 1002 I 
3 13 103 1003 U 
4 14 104 1004 B 

我已经做了这样的:

q)update r:(flip (a+b;c+d;a-d))@'`I`B`U?g from t 
a b c d g r  
--------------------- 
0 10 100 1000 I 10 
1 11 101 1001 B 1102 
2 12 102 1002 I 14 
3 13 103 1003 U -1000 
4 14 104 1004 B 1108 

问题 - 有更有效的方式(时间,空间,代码行)?

回答

1

这类似于你的解决方案,但似乎约30%的速度,可能是因为没有flip

q)update r: ((a+b;c+d;a-d)@(`I`B`U?g))@'i from t 
a b c d g r 
--------------------- 
0 10 100 1000 I 10 
1 11 101 1001 B 1102 
2 12 102 1002 I 14 
3 13 103 1003 U -1000 
4 14 104 1004 B 1108 

q)t:1000000?t 
q)\t update r: ((a+b;c+d;a-d)@(`I`B`U?g))@'i from t 
166 
q)\t update r:(flip (a+b;c+d;a-d))@'`I`B`U?g from t 
248 

尽管嵌套条件仍然看起来更快:

q)\t update r:?[`I=g;a+b;?[`B=g;c+d;a-d]] from t 
46 
+0

'@'我'是辉煌!在我继续从右至左重复使用“@”系列之前,我有一种新的成语。谢谢! –

1

可以使用条件的载体: http://code.kx.com/q/ref/lists/#vector-conditional

q)update r:?[`I=g;a+b;c+d] from t 
    a b c d g r 
    -------------------- 
    0 10 100 1000 I 10 
    1 11 101 1001 B 1102 
    2 12 102 1002 I 14 
    3 13 103 1003 I 16 
    4 14 104 1004 B 1108 

编辑: 当G有多个值超过两个,你可以进一步嵌套条件扩展:

q)\t res2:delete idx from`idx xasc raze{[t;idx;it;k] @[d;`idx`r;:;](idxs; 
    (+).(d:t idxs:idx[it])k)}[t;group t`g;]./:flip(`I`C`B;(`a`b;`b`c;`c`d)) 
    122 
    q) 
    q)\t res3:update r:?[`I=g;a+b;?[`B=g;c+d;a-d]] from t 
    59 
    q)res3~res2 
    1b 
+0

编辑了这个问题。克可以有更多的价值比两个 –

0

可以使用可信赖字典。把你的可能值作为键和作为值的函数。你甚至可以根据你在表中的键值的实际数量动态地生成这个函数。我相信这在性能方面不是最好的。

q)fd:`I`B`C!({(+). [email protected]`a`b};{(+). [email protected]`b`d};{(+). [email protected]`c`d}) 
    q)update r:{(fd x[`g])x}each t from t 
    a b c d g r 
    -------------------- 
    0 10 100 1000 I 10 
    1 11 101 1001 B 1012 
    2 12 102 1002 I 14 
    3 13 103 1003 C 1106 
    4 14 104 1004 B 1018 
    q) 

*编辑 更快的方法,并比较...

q)t:1000000?t 
    q)fd:`I`B`C!({(+). [email protected]`a`b};{(+). [email protected]`c`d};{(+). [email protected]`b`c}) 
    q)\t res1:update r:{(fd x[`g])x}each t from t 
    635 
    q)\t res2:delete idx from`idx xasc raze{[t;idx;it;k] @[d;`idx`r;:;](idxs;(+).(d:t idxs:idx[it])k)}[t;group t`g;]./:flip(`I`C`B;(`a`b;`b`c;`c`d)) 
    79 
    q)res1~res2 
    1b 
    q)