在KDB +中具有多个值列的数据透视表

时间:2020-02-07 08:48:41

标签: q kdb

我想转换以下两行生成的表:

tb: ([] time: 2010.01.01 2010.01.01; side:`Buy`Sell; price:100 101; size:30 50)

time        side    price   size
--------------------------------
2010.01.01  Buy     100     30
2010.01.01  Sell    101     50

到下表中的单行:

tb1: ([] enlist time: 2010.01.01; enlist price_buy:100; enlist price_sell:101; enlist size_buy:30; enlist size_sell:50)

time        price_buy price_sell size_buy size_sell
-----------------------------------------------------
2010.01.01  100       101        30       50

最有效的方法是什么?

3 个答案:

答案 0 :(得分:4)

(select price_buy:price, size_buy:size by time from tb where side = `Buy) lj select price_sell:price, size_sell:size by time from tb where side = `Sell

time      | price_buy size_buy price_sell size_sell
----------| ---------------------------------------
2010.01.01| 100       30       101        50

如果要避免使用2条select语句:

raze each select `price_buy`price_sell!(side!price)@/:`Buy`Sell, `size_buy`size_sell!(side!size)@/:`Buy`Sell by time from tb

作为附加说明,将日期列标记为时间可能会引起误解。 kdb中典型的财务表的格式为date time sym etc

编辑:动态列生成的功能形式:

{x[0] lj x[1]}[{?[`tb;enlist (=;`side;enlist `$x);(enlist `time)!enlist `time;(`$("price",x;"size",x))!(`price;`size)]} each ("Sell";"Buy")] time | priceSell sizeSell priceBuy sizeBuy ----------| ----------------------------------- 2010.01.01| 101 50 100 30

答案 1 :(得分:2)

Kx网站上的常规数据透视功能可以做到这一点,请参见https://code.kx.com/q/kb/pivoting-tables/

q)piv[tb;(),`time;(),`side;`price`size;{[v;P]`$raze each string raze P[;0],'/:v,/:\:P[;1]};{x,z}]
time      | Buyprice Sellprice Buysize Sellsize
----------| -----------------------------------
2010.01.01| 100      101       30      50

答案 2 :(得分:1)

我在github中有一个透视功能。但是它不支持多列

.math.st.pivot: {[t;rc;cf;ff]
  P: asc distinct t cf;
  Pcol: `$string[P] cross "_",/:string key ff;
  t: ?[t;();rc!rc;key[ff]!{({[x;y;z] z each y@group x}[;;z];x;y)}[cf]'[key ff;value ff]];
  t: ![t;();0b; Pcol! raze {((';@);x;$[-11h=type y;enlist;::] y)}'[key ff]'[P] ];
  ![t;();0b;key ff]
};

但是您可以退出加入以获得预期结果:

.math.st.pivot[tb;enlist`time;`side;enlist[`price]!enlist first]
  lj .math.st.pivot[tb;enlist`time;`side;enlist[`size]!enlist first]

好像添加对多列的支持是个好主意。