[KDB + / Q]:嵌套向量条件

时间:2017-06-13 13:56:58

标签: kdb q-lang

如何根据其他向量的值有效而简洁地切换公式?

根据kx documentation,可以

  

不仅仅包含真/假选择,例如match1 / match2 / match3 /其他映射到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 

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

3 个答案:

答案 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的值大于2,则可以使用嵌套条件进一步扩展:

   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

答案 1 :(得分: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

答案 2 :(得分:0)

您可以使用可信词典。将您的可能值作为键,将函数作为值。您甚至可以根据表中的实际键值来动态生成此函数。我确信这在性能方面并不是最好的。

import telegram

def start(bot, update):

    kb = [[telegram.KeyboardButton('/command1')],
          [telegram.KeyboardButton('/command2')],
          [telegram.KeyboardButton('/command3')]]
    kb_markup = telegram.ReplyKeyboardMarkup(kb, resize_keyboard=True)

    bot.send_message(chat_id=update.message.chat_id,
                     text="Welcome!",
                     reply_markup=kb_markup)

*编辑 更快的方法和比较...

    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)