[KDB+/Q]:嵌套向量条件
[KDB+/Q]: Nested vector conditional
如何根据其他向量的值高效简洁地切换公式?
根据kx documentation,可以
have more than just a true/false selection, e.g. match1/match2/match3/others mapping to result1/result2/result3/default
数据:
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
问题 - 有没有更有效的方法(时间,space,代码行数)?
您可以使用条件向量:
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
您可以使用可信赖的词典。将可能的值作为键,将函数作为值。您甚至可以根据 table 中键值的实际数量动态生成此函数。我敢肯定这在性能方面不是最好的。
q)fd:`I`B`C!({(+). x@`a`b};{(+). x@`b`d};{(+). x@`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!({(+). x@`a`b};{(+). x@`c`d};{(+). x@`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)
这与您的解决方案类似,但似乎快了大约 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
如何根据其他向量的值高效简洁地切换公式?
根据kx documentation,可以
have more than just a true/false selection, e.g. match1/match2/match3/others mapping to result1/result2/result3/default
数据:
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
问题 - 有没有更有效的方法(时间,space,代码行数)?
您可以使用条件向量: 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
您可以使用可信赖的词典。将可能的值作为键,将函数作为值。您甚至可以根据 table 中键值的实际数量动态生成此函数。我敢肯定这在性能方面不是最好的。
q)fd:`I`B`C!({(+). x@`a`b};{(+). x@`b`d};{(+). x@`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!({(+). x@`a`b};{(+). x@`c`d};{(+). x@`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)
这与您的解决方案类似,但似乎快了大约 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