KDB边际百分比

时间:2014-08-12 17:10:24

标签: kdb

考虑表格T,列表时,如下所示:

select sum Qty by Flag1,Flag2 from T

Flag1 Flag2 Qty
`Sunny `Hot 20
`Sunny `Cold 40
`Rainy `Hot 60
`Rainy `Cold 80

1)是否有一种很好的方法来计算每个桶中的总数量的总分数(0.1,0.2,0.3,0.4)?显然,人们可以做类似

的事情
select Qty % sum Qty from select sum Qty by Flag1,Flag2 from T

但无论如何都要一举做到这一点(即只有一个select / exec语句),因为如果你为很多变量做这件事,这会有点麻烦吗?

2)现在想象一下,我想创建一个具有相对分数Qty但被Flag1边缘化的列。如何创建下表?

Flag1 Flag2 Qty FracByFlag1
`Sunny `Hot 20  0.333
`Sunny `Cold 40 0.667
`Rainy `Hot 60 0.429
`Rainy `Cold 80 0.571

3 个答案:

答案 0 :(得分:1)

您可能需要考虑将其设为功能形式查询

more info on functional form here

q)t:([]f1:raze 2#'`s`r; f2:4#`h`c; qty:20 40 60 80)
q)p:{![x;();y;enlist[`pct]!enlist (%;z;(sum;z))]}
q)p[t;0b;`qty]
f1 f2 qty pct
-------------
s  h  20  0.1
s  c  40  0.2
r  h  60  0.3
r  c  80  0.4
q)p[t;enlist[`f1]!enlist `f1;`qty]
f1 f2 qty pct      
-------------------
s  h  20  0.3333333
s  c  40  0.6666667
r  h  60  0.4285714
r  c  80  0.5714286

答案 1 :(得分:1)

我认为你必须加重一些“漂亮”的好处,而不是高效和易于阅读的东西。双重选择可能只是更好的方法。

一个有趣的扩展是这样的:如果你需要根据不同的标志看到不同的子比率,但是在同一个表中(以及在一个选择中)?下面的解决方案可以实现这一点但是我再次强调这种方法效率非常低 - 只是出于“漂亮”的目的而显示它

q)T:([] Flag1:`Sunny`Sunny`Sunny`Sunny`Rainy`Rainy`Rainy`Rainy;Flag2:`Hot`Hot`Cold`Cold`Hot`Hot`Cold`Cold;Qty:10 10 20 20 30 30 40 40);
q)
q)T
Flag1 Flag2 Qty
---------------
Sunny Hot   10
Sunny Hot   10
Sunny Cold  20
Sunny Cold  20
Rainy Hot   30
Rainy Hot   30
Rainy Cold  40
Rainy Cold  40

q)myGroup:{@[;raze g] raze s%sum each s:sum each flip each y g:group x}
q)
q)select Flag1,Flag2,sum'[Qty],both:sum'[Qty]%sum raze Qty,f1:myGroup[Flag1;Qty],f2:myGroup[Flag2;Qty] from `Flag1`Flag2 xgroup T
Flag1 Flag2 Qty both f1        f2
----------------------------------------
Sunny Hot   20  0.1  0.3333333 0.25
Sunny Cold  40  0.2  0.6666667 0.3333333
Rainy Hot   60  0.3  0.4285714 0.75
Rainy Cold  80  0.4  0.5714286 0.6666667

答案 2 :(得分:0)

1)我认为在分割期间分别总计列数量是最简单的:

update (sum Qty) % sum T[`Qty] by Flag1, Flag2 from T

2)fby正如你所追求的那样:

update FracByFlag1: Qty % (sum;Qty) fby Flag1 from T