Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

[KDB+/Q]: Nested vector conditional

Tags:

q-lang

kdb+

How to efficiently and concisely switch formulas dependent on the value of other vector?

According to kx documentation, it is possible to

have more than just a true/false selection, e.g. match1/match2/match3/others mapping to result1/result2/result3/default

Data:

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

I've done it like this:

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 

Question - is there more efficient way (time,space,lines of code)?

like image 413
Daniel Krizian Avatar asked Feb 27 '26 01:02

Daniel Krizian


2 Answers

This is similar to your solution, but seems about 30% faster, possibly because there's no 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

Although the nested conditional still looks faster:

q)\t update r:?[`I=g;a+b;?[`B=g;c+d;a-d]] from t
46
like image 117
James Little Avatar answered Mar 03 '26 17:03

James Little


You can use a vector conditional: 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

Edit: If g has more values than two you can extend further with nested conditionals:

   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
like image 28
jomahony Avatar answered Mar 03 '26 17:03

jomahony



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!