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 的前两列 symbol
和 provider
重复了三次,而 px
列是 px1
的串联, px2
和 px3
,与 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))
此处的 a
和 b
列提供排序索引,稍后会从结果中删除。 运行 的时间在 1m 行上约为 180ms,因此仍然比 ungroup 方法快约 9 倍。当然,排序的存在会使该算法比线性算法更差,但是它还有很大的空间可以更快地达到大约 100m 行(不幸的是现在无法测试)
使用 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
我有一个市场数据 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 的前两列 symbol
和 provider
重复了三次,而 px
列是 px1
的串联, px2
和 px3
,与 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))
此处的 a
和 b
列提供排序索引,稍后会从结果中删除。 运行 的时间在 1m 行上约为 180ms,因此仍然比 ungroup 方法快约 9 倍。当然,排序的存在会使该算法比线性算法更差,但是它还有很大的空间可以更快地达到大约 100m 行(不幸的是现在无法测试)
使用 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