KDB - 折叠市场数据中的列 table

KDB - collapse columns in market data table

我有一个市场数据 table,其中包含一系列市场供应商和符号的订购价格和数量数据,例如

b:([]symbol:();provider:();px1:();px2:();px3:();qty1:();qty2:();qty3:())

其中 px1 是数量为 qty1 的账簿顶部,px2 是下一个最佳价格等。样本数据可能是

`EURUSD;`EBS;1.1;1.2;1.3;1000000;2000000;4000000

我想将 px[n] 和 qty[n] 列折叠成单列,格式为;

rb:([]symbol:();provider:();px:();qty:())

用样本数据读取;

EURUSD, EBS, 1.1, 1000000
EURUSD, EBS, 1.2, 2000000
EURUSD, EBS, 1.3, 4000000

实现此目标的最佳方法是什么?作为一个新手,我一直在考虑使用字典;

q)px:book `px1`px2`px3
q)qty:book `qty1`qty2`qty3
q)d:`px`qty!(px;qty)
q)flip d
px  qty
-----------
1.1 1000000
1.2 2000000
1.3 4000000

...但我相信还有更好的方法。

如果您无法重构原始 table 定义,则可以使用以下内容。

q)b
symbol provider px1 px2 px3 qty1    qty2    qty3
---------------------------------------------------
EURUSD EBS      1.1 1.2 1.3 1000000 2000000 4000000
EURUSD ECS      1.1 1.2 1.3 1000000 2000000 4000000
q)ungroup {rm _x,'flip enlist[y]!enlist flip x rm:cols[x]where cols[x] like string[y],"*" }/[b;\`px\`qty]

symbol provider px  qty
---------------------------
EURUSD EBS      1.1 1000000
EURUSD EBS      1.2 2000000
EURUSD EBS      1.3 4000000
EURUSD ECS      1.1 1000000
EURUSD ECS      1.2 2000000
EURUSD ECS      1.3 4000000

Connor 的回答可能是最规范的,但是 ungroup 仍然是 table 的迭代,根据定义,它比直接列表操作慢。在许多情况下,迭代是不可避免的,但在这里您可以直接从输入 table 的列表构造结果 table,如下所示:

flip `symbol`provider`px`qty!(
                (3*cb)#b`symbol; 
                (3*cb:count[b])#b`provider; 
                (b[`px1],b[`px2],b`px3); 
                (b[`qty1],b[`qty2],b`qty3)) 

这里的结果 table 的前两列 symbolprovider 重复了三次,而 px 列是 px1 的串联, px2px3,与 qty 相同。

当然,此方法不会产生与 ungroup 相同的行顺序,但有趣的一点是它快 运行s ~40 倍(1m 行大约 40ms,取消分组大约 1600ms) .

如果需要保留记录的顺序,我们可以对它们进行编号,然后排序:

`a`b _ `a`b xasc flip `a`b`symbol`provider`px`qty!(
    (3*cb)#til[cb]; 
    raze cb#/:(til 3); 
    (3*cb)#b`symbol; 
    (3*cb:count[b])#b`provider; 
    (b[`px1],b[`px2],b`px3); 
    (b[`qty1],b[`qty2],b`qty3)) 

此处的 ab 列提供排序索引,稍后会从结果中删除。 运行 的时间在 1m 行上约为 180ms,因此仍然比 ungroup 方法快约 9 倍。当然,排序的存在会使该算法比线性算法更差,但是它还有很大的空间可以更快地达到大约 100m 行(不幸的是现在无法测试)

使用 flipungroup 完成它的一种方法:

q)b:([]symbol:`eurjpy`eurusd;provider:2#`ebs;px1:10+2?.1;px2:11+2?.1;px3:12+2?.1;qty1:100+2?10;qty2:100+2?10;qty3:100+2?10)

symbol provider px1      px2      px3      qty1 qty2 qty3
---------------------------------------------------------
eurjpy ebs      10.05641 11.04464 12.02366 109  103  107
eurusd ebs      10.01925 11.08214 12.07947 104  104  102

q)ungroup select symbol, provider, px:flip (px1;px2;px3) , qty:flip (qty1;qty2;qty3)  from b
symbol provider px       qty
----------------------------
eurjpy ebs      10.05641 109
eurjpy ebs      11.04464 103
eurjpy ebs      12.02366 107
eurusd ebs      10.01925 104
eurusd ebs      11.08214 104
eurusd ebs      12.07947 102