【问题标题】:(kdb+/q) Pivot table: date in rows, symbols in columns, last price as values(kdb+/q) 数据透视表:行中的日期,列中的符号,最后的价格作为值
【发布时间】:2015-05-05 14:11:29
【问题描述】:

http://code.kx.com/q/cookbook/pivoting-tables/ 提供的通用数据透视函数转到:

piv:{[t;k;p;v;f;g]
 v:(),v;
 G:group flip k!(t:.Q.v t)k;
 F:group flip p!t p;
 count[k]!g[k;P;C]xcols 0!key[G]!flip(C:f[v]P:flip value flip key F)!raze
  {[i;j;k;x;y]
   a:count[x]#x 0N;
   a[y]:x y;
   b:count[x]#0b;
   b[y]:1b;
   c:a i;
   c[k]:first'[a[j]@'where'[b j]];
   c}[I[;0];I J;J:where 1<>count'[I:value G]]/:\:[t v;value F]}

鉴于fg 被定义为

 f:{[v;P]`$raze each string raze P[;0],'/:v,/:\:P[;1]}
 g:{[k;P;c]k,(raze/)flip flip each 5 cut'10 cut raze reverse 10 cut asc c}

现在这个例子可以工作了(参见上面的链接如何定义表q):

piv[`q;`date`sym`time;`side`level;`price`size;f;g]

date       sym  time        | Bprice0 Bsize0 Aprice0  Asize0 Bprice1  Bsize1 ..
----------------------------| -----------------------------------------------..
2009.01.05 milg 09:30:00.187|                                93.56285 29     ..
2009.01.05 milg 09:30:15.798|                                                ..
2009.01.05 milg 09:30:30.627|                                                ..

在我的情况下,我想以sym(每列不同的符号)为轴,并以date(每行不同的日期)为键,值最后price(每个单元格在给定日期的最后价格和符号)。

这种天真的调用不起作用:

piv[`q;`date;`sym;`price;f;g]

如何重新定义 fg 函数以获取每个不同日期和每个符号的最后价格表,从而产生类似的结果?

date       |  syma    symb     symc 
-----------| ----------------------
2009.01.05 | 93.56     8.5    566.1
2009.01.06 | 93.6      8.0    564.2
2009.01.07 |           9.0         
2009.01.08 | 94.05            560.3

【问题讨论】:

    标签: pivot-table kdb q-lang


    【解决方案1】:

    函数piv 要求keypivot 参数是一个列表。因此,如下修改您的幼稚调用会给我们一个结果:

    q) piv[`q;(),`date;(),`sym;`price;f;g]
        date      | obhmprice oijbprice mkjkprice nihdprice ldegprice mbgnprice jmmip..
        ----------| -----------------------------------------------------------------..
        2009.01.08| 72.35531  28.9323   23.88535  12.21371  2.417089  49.45298  98.14..
        2009.01.07| 83.59946  6.036849  21.47751  78.8127   10.8295   98.52086  92.95..
        2009.01.09| 46.80912  46.26248  81.22377  93.51525  22.72674  95.42947  0.780..
        2009.01.05| 15.15728  26.88241  52.27362  90.73569  46.13635  50.67675  36.28..
        2009.01.06| 87.55843  38.49544  44.47115  59.41535  28.59271  94.38644  72.12..
    

    ...值为最后价格...

    您需要对报价数据进行如下预处理以获得最新价格:

    q) piv[0!select last price by date,sym from `date`time xasc q;(),`date;(),`sym;`price;f;g]
        date      | obhmprice oijbprice mkjkprice nihdprice ldegprice mbgnprice jmmip..
        ----------| -----------------------------------------------------------------..
        2009.01.05| 68.45829  95.92887  55.64212  82.06286  86.33655  6.020653  49.99..
        2009.01.06| 80.80825  39.97803  44.47115  20.84011  95.24609  26.23889  21.87..
        2009.01.07| 30.9605   15.85936  2.112642  74.48924  63.82276  49.55288  9.791..
        2009.01.08| 40.17655  34.08045  49.43202  59.99883  68.43116  74.76724  96.43..
        2009.01.09| 5.628707  96.54884  93.37123  65.68942  12.78308  91.10505  59.37..
    

    最后,要使列名成为符号名,您需要修改 fg 函数 - 可以查看文档 here 或简单地添加一些调试打印以查看传递给这些函数的内容了解它们应该是什么的功能。

    在您的情况下,它们可以简单地设置为以下内容:

    q) piv[0!select last price by date,sym from `date`time xasc q;(),`date;(),`sym;`price;{y[;0]};{x,z}]
        date      | abaa     aeec     agom     ahnj     amlj     aogk     bbfc     be..
        ----------| -----------------------------------------------------------------..
        2009.01.05| 1.382202 16.05533 33.8328  31.08264 82.60021 87.60909 37.37758 82..
        2009.01.06| 14.96261 35.70751 11.48701 5.394078 47.38052 79.5398  31.46943 64..
        2009.01.07| 12.95503 17.96305 92.59666 89.16665 83.80779 15.04835 34.70387 9...
        2009.01.08| 39.33969 15.18487 2.20252  8.859751 43.23156 22.88771 15.73866 76..
        2009.01.09| 48.32295 18.01393 91.38    46.87793 45.88258 67.70167 57.27067 63..
    

    【讨论】:

    • 感谢您的见解,它适用于我的情况,除了我必须定义 f:{[v;P] `$raze each string raze P[;0]} 而不是您的提议 f:{y[;0]}(或 f:{P[;0]}
    • 辅助问题:code.kx.com/wiki/Pivot 表示 fg 可以默认使用 (::) - 在这种情况下语法会是什么样子?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-03
    • 1970-01-01
    • 2015-11-25
    相关资源
    最近更新 更多