KDB/Q:根据其他列的值创建一个新列

KDB/Q: create a new column based on the value of other columns

这可能是一个简单的问题,但我无法让它工作。如果 var1var2 中只有一列的值为 1,我正在尝试创建等于列 Price 一半的列 varNewvar1var2只取0或1的值。如果var1var2都为1则varNew = Price。所以想要的数据看起来像这样

var1    var2    Price   varNew
0       0       10      10
0       1       14      7
1       0       12      6
1       1       20      20

我试过了:

update varNew:?[((var1+var2)>0);Price%2;Price] from table

varNew:?[(var1=1 and var2=0)|(var1=0 and var2=1);Price%2;Price] from table

varNew:?[var1=1 or var2=1;Price%2;Price] from table

但它们没有按预期工作。特别是,它 returns 12 而不是 6。 到底是怎么回事?为什么这些条件不起作用?我应该怎么做?

一个解决方案是:

 q)t:([]var1:0011b;var2:0101b;Price:10 14 12 20)
 q)update varNew:?[var1<>var2;Price%2;Price] from t

这是 ? 的众多重载之一运算符(https://code.kx.com/q/ref/overloads/#query)。在这种形式中,它用作条件向量。

进一步解释您的方法为何无效

update varNew:?[((var1+var2)>0);Price%2;Price] from table

(var1+var2)>0 包括 var1 和 var2 都等于 1,导致最后的价格除以 2,这不是本意

varNew:?[(var1=1 and var2=0)|(var1=0 and var2=1);Price%2;Price] from table

q 从右到左计算(也称为 Left-of-Right evaluation),这意味着您的代码实际上正在执行此操作(一旦添加了隐式括号)

var1=1 and var2=0 => (var1=(1 and (var2=0)))
var1=0 and var2=1 => (var1=(0 and (var2=1)))

1 and 将始终保持右侧不变,第二行的 0 and 将始终 return 0,因此整行简化为:

varNew:?[(var1=(var2=0))|(var1=0);Price%2;Price] from table

这与您尝试编码的条件不同。要解决此问题,您可以添加额外的括号以确保按您的预期进行评估,尽管 Dan 的回答效率更高

varNew:?[((var1=1) and var2=0)|((var1=0) and var2=1);Price%2;Price] from table