KDB - 折叠市场数据表

时间:2016-05-03 15:34:51

标签: 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:();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

......但我确信有更好的方法。

3 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:1)

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)) 

此处结果表的前两列symbolprovider重复三次,px列是px1px2的串联, px3qty也一样。

当然这个方法不会产生与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)) 

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

答案 2 :(得分:0)

使用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