识别行的N个最大值,从表行

时间:2018-01-08 16:59:22

标签: kdb q-lang

我遇到了以下问题,并希望得到一些帮助。我尝试了一些事情,并使用了Stack Overflow上的一些信息(例如this/How to apply max function for each row in KDB?this/Iterate over current row values in kdb query,然后翻转然后滑动窗口为per my previous post),然后翻过我的{{再次,但由于某种原因,我撞到了一堵砖墙。

在我的表中,第一列是日期列,其余是数字。从这开始我试图生成一个只剩下Q for Mortals个最大行数的表,其余的设置为零或n(或者,如果你愿意的话,{{1}底部值已被丢弃)。

示例:

起始表:

0N

在识别每行2个最大值并消隐其余部分(使用0或m)时所需的最终结果:

q)t:([] td:2001.01.01 2001.01.02 2001.01.03 2001.01.04 2001.01.05 2001.01.06; 
AA:121.5 125.0 127.0 126.0 129.2 130.0; BB:111.0 115.3 117.0 116.0 119.2
120.0; CC:120.0 126.0 125.5 128.8 135.0 130.0; DD:120.1 123.3 128.4 128.3 
127.5 126.0; NN:122.0 125.5 126.0 116.0 109.0 100.5)

td         AA    BB    CC    DD    NN   
----------------------------------------
2001.01.01 121.5 111   120   120.1 122  
2001.01.02 125   115.3 126   123.3 125.5
2001.01.03 127   117   125.5 128.4 126  
2001.01.04 126   116   128.8 128.3 116  
2001.01.05 129.2 119.2 135   127.5 109  
2001.01.06 130   120   130   126   100.5

以第1行为例,该行的AA和NN中的前2个值已被保留,而BB和CC中的其他两个值已被消隐。

要仅获取最大值,即一个最高值,我可以执行以下操作,并在后续0n语句中使用新添加的列。但是,这里的问题是我需要找到td AA BB CC DD NN ------------------------------------- 2001.01.01 121.5 122 2001.01.02 126 125.5 2001.01.03 127 128.4 2001.01.04 128.8 128.3 2001.01.05 129.2 135 2001.01.06 130 130 maxes并丢弃其余部分。

update

不确定它是否有任何意义,但作为我尝试过的一个例子:如果我使用来自另一个堆栈溢出帖子的提示并且我在值本身上执行它我可以到达那里,但不是在表格式:

n

然而,当我尝试将此作为更新的一部分或选择时,它不起作用;这也是一个非q方法让我感到非常兴趣,因为他们对解决上述问题的人们有什么兴趣。

另一个例子是我尝试翻转表然后使用MMAX,但是由于日期位于顶部,他们“幸存”。此外,如果我对q)update maxes:max(AA;BB;CC;DD;NN) from t maxes感兴趣,或者删除构成底部值的q)nthMax:{x (idesc x)[y-1]} {x (idesc x)[y-1]} q)nthMax[(121.5 111 120 120.1 122);1] 122f q)nthMax[(121.5 111 120 120.1 122);2] 121.5 数字,那么这似乎有点笨拙,因为我必须每列n次执行此操作留下n个最大数字。

亲切的问候, 斯文

3 个答案:

答案 0 :(得分:4)

如果您不希望列保持相同的顺序,以下内容将为您提供正确的结果:

key[kt]!(uj/) value {enlist (2#idesc x)#x}each kt:1!t

结果:

td        | NN    AA    CC    DD      
----------| -----------------------   
2001.01.01| 122   121.5               
2001.01.02| 125.5       126           
2001.01.03|       127         128.4   
2001.01.04|             128.8 128.3   
2001.01.05|       129.2 135           
2001.01.06|       130   130           

您可以在" xcols"之后修复订单。如果它对你很重要,或者这样做(这个时间稍长但保留了从不在前n的列)

q)key[kt]!(uj/) value {enlist (key[x]!count[x]#0n),(2#idesc x)#x}each kt:1!t

td        | AA    BB CC    DD    NN                                         
----------| --------------------------                                      
2001.01.01| 121.5                122                                        
2001.01.02|          126         125.5                                      
2001.01.03| 127            128.4                                            
2001.01.04|          128.8 128.3                                            
2001.01.05| 129.2    135                                                    
2001.01.06| 130      130       

答案 1 :(得分:3)

这是另一种选择,可能有点整洁:

q)0!{key[x]#(2#idesc x)#x}'[1!t]
td         AA    BB CC    DD    NN
-------------------------------------
2001.01.01 121.5                122
2001.01.02          126         125.5
2001.01.03 127            128.4
2001.01.04          128.8 128.3
2001.01.05 129.2    135
2001.01.06 130      130

这是假设第一列是您不想考虑的最大值。它与idesc使用的其他两个答案类似。这里要注意的一部分是key[x]#,它基本上将空条目添加到字典中以确保所有键都存在。作为一个例子:

q)`a`b`c#`a`c!1 2
a| 1
b|
c| 2

注意b在结果字典中是如何存在但在原始字典中不是。这用于确保为每行生成的字典与其他行一致,从而生成一个表(毕竟,它只是一个符合字典的列表)。

答案 2 :(得分:1)

这是一个丑陋的代码,应该适用于您的示例:

heroku addons:add

该函数允许您指定应包含哪些列以及每行中的值。