KDB-市场数据表中的折叠列
我有一个包含订购价格和数量数据的市场数据表,用于一系列市场供应商和符号,例如KDB-市场数据表中的折叠列,kdb,Kdb,我有一个包含订购价格和数量数据的市场数据表,用于一系列市场供应商和符号,例如 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:();pr
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
。。。但是我相信还有更好的方法。如果不能重新构造原始表定义,可以使用以下方法
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
仍然是表上的迭代,根据定义,它比直接列表操作慢。在许多情况下,迭代是不可避免的,但在这里,您可以直接从输入表的列表构建结果表,如下所示:
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))
这里,结果表的前两列symbol
和provider
重复三次,px
列是px1
、px2
和px3
的串联,与quantity
相同
当然,这种方法不会产生与ungroup
相同的行顺序,但有趣的是,它的运行速度快了约40倍(对于1m行,大约40ms,ungroup大约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))
这里的
a
和b
列提供了用于排序的索引,稍后将从结果中删除。此方法在1m行上的运行时间约为180ms,因此仍然比ungroup方法快9倍。当然,排序的存在会使该算法比线性算法更差,但它仍有很大的余量,可以更快地达到大约100万行(不幸的是,现在无法测试)使用flip
和ungroup
完成排序的一种方法:
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
您可以使用
raze flip b[`px1`px2`px3]
来维护价格和数量列的顺序,并使用(`symbol`provider#b)在count[x]#3