如何有效地将一个 KDB 函数的输出转换为三个 table 列?

How can I efficiently convert the output of one KDB function into three table columns?

我有一个函数,可以将 table 和 return 中的一些值作为输入,如果你愿意的话 - 三个独立的 return 值,我想转置到查询的输出中。这是我想要实现的目标的简化示例:

multiplier:{(x*2;x*3;x*3)};
select twoX:multiplier[price][0]; threeX:multiplier[price][1]; fourX:multiplier[price][2] from data;

以上基本有效(我认为我的简化示例的语法正确 - 如果不是,那么希望我的意图很明确),但效率低下,因为我调用了该函数三次并丢弃了大部分每次的输出。我想重写查询以仅调用一次函数,但我很挣扎。

更新

我想我在解释影响结果的问题时遗漏了一条重要信息——我需要在查询中获取其他数据以及函数的输出。这是一个希望更现实的例子:

multiplier:{(x*2;x*3;x*4)};
select average:avg price, total:sum price, twoX:multiplier[sum price][0]; threeX:multiplier[sum price][1]; fourX:multiplier[sum price][2] by category from data;

无论如何,我都会尝试调整您的答案以满足此要求,对于遗漏了这一点信息,我们深表歉意。如果专有且相当复杂的算法和实际查询具有大约 30 个输出列,则为实际功能,因此尝试简化示例 :)

如果您只是自己寻找结果,您可以提取 (exec) 作为列表,创建字典,然后将字典翻转成 table:

q)exec flip`twoX`threeX`fourX!multiplier[price] from ([]price:til 10)
twoX threeX fourX
-----------------
0    0      0
2    3      4
4    6      8
6    9      12
8    12     16
10   15     20
12   18     24
14   21     28
16   24     32
18   27     36

如果您还需要原始 table 中的其他列,那么它会更棘手,但您可以使用 ,'

横向加入 tables
q)t:([]price:til 10)
q)t,'exec flip`twoX`threeX`fourX!multiplier[price] from t

一个apply@也可以达到你想要的效果。这里 data 只是具有 10 个随机价格的 table。 @ 然后用于将 multiplier 函数应用于 price 列,同时还为三个结果列表中的每一个分配一个列名:

q)data:([] price:10?100)
q)multiplier:{(x*2;x*3;x*3)}
q)@[data;`twoX`threeX`fourX;:;multiplier data`price]
price twoX threeX fourX
-----------------------
80    160  240    240
24    48   72     72
41    82   123    123
0     0    0      0
81    162  243    243
10    20   30     30
36    72   108    108
36    72   108    108
16    32   48     48
17    34   51     51