Kdb 标识行的N个最大值,丢弃表行中剩余的底部值

Kdb 标识行的N个最大值,丢弃表行中剩余的底部值,kdb,q-lang,Kdb,Q Lang,我遇到了以下问题,希望能得到一些帮助。我尝试了一些方法,并使用了在堆栈溢出上找到的一些信息(例如和,然后翻转滑动窗口作为),再次浏览了我的Q for manters,但出于某种原因,我遇到了麻烦 在我的表中,第一列是日期列,其余是数字。我试图由此生成一个表,该表只剩下n最大行数,其余的设置为零或0N(或者,如果您愿意,也可以忽略m底部值) 例如: 起始表: q)t:([] td:2001.01.01 2001.01.02 2001.01.03 2001.01.04 2001.01.05 2001

我遇到了以下问题,希望能得到一些帮助。我尝试了一些方法,并使用了在堆栈溢出上找到的一些信息(例如和,然后翻转滑动窗口作为),再次浏览了我的
Q for manters
,但出于某种原因,我遇到了麻烦

在我的表中,第一列是日期列,其余是数字。我试图由此生成一个表,该表只剩下
n
最大行数,其余的设置为零或
0N
(或者,如果您愿意,也可以忽略
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
识别每行2个最大值并将其余值(0或
0n
)置空时的预期最终结果:

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

要仅获取最大值,即一个最大值,我可以执行以下操作,并在后续
update
语句中使用新添加的列。然而,这里的问题是,我需要找到
n
maxes并丢弃其余的

q)update maxes:max(AA;BB;CC;DD;NN) from t
不确定这是否有什么意义,但作为我尝试过的一个例子:如果我使用另一个堆栈溢出帖子中的提示,并在值本身上执行该提示,我可以在某种程度上到达那里,但不是以表格格式:

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
但是,当我尝试将其用作更新或选择的一部分时,它就不起作用了;此外,我觉得它是一种非q方法,对人们如何解决上述问题非常感兴趣

另一个例子是,我尝试翻转表格,然后使用MMAX,但是由于日期在顶部,所以它们“存活”。此外,这似乎有点笨重,因为如果我对
n
maxes感兴趣,我必须在每列中执行
n
次,或者删除构成底部值的
x
数字,留下
n
最大数字

亲切问候,,
Sven

如果不需要列保持相同的顺序,则以下操作将获得正确的结果:

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中的列)


下面是一段难看的代码,适用于您的示例:

{x,'flip y!flip{?[x>idesc y;y;0N]}[z]each flip x y}[t;`AA`BB`CC`DD`NN;2]
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

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

这里还有另一个选项,可能会稍微整洁一些:

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在结果字典中的位置,而不是在原始字典中的位置。这用于确保为每一行生成的字典与其他行一致,从而生成一个表(毕竟,这只是一个一致字典的列表)。

虽然我不知道您在这里的用例,但通常情况下,如果您最终不得不跨行执行逻辑/操作(与列式操作相反)则可能无法以最佳方式设置数据/表。如果表中有一列用于值,一列用于相关标题(AA、BB、CC等),则可以更轻松地执行此操作(对于大型数据集也更有效)。如果您真的需要输出为一个稀疏/宽的空白表,那么您可以旋转结果我想知道这是否是一个问题-我将开始像这样组织数据,因为数据集可能非常大(数百万)因此,速度和效率是值得关注的。非常感谢,我将在稍后的连接处重新构造数据。再次感谢Thomas-我希望避免在列名更改时引用列名,通常是20-100个。很高兴看到一些翻转魔术,但我确实为我的模型的另一部分选择了一些我需要的东西。如果你有大量的数据对于列,您可以使用“cols[t]除了'td'之外”来代替列名,因为正如您在原始问题中所说的,您有一个日期列,其余的应该包括在内。非常感谢Paul,我不必引用列是非常方便的。不必创建带有
(键[x]!count[x]的虚拟字典#0n)
,您可以使用
键[x]#
实现同样的效果-请参见下面的答案以获取示例。您还可以丢失
登记
,这应该可以在所有COL都存在时停止使用
uj
(上一个示例)。这确实更整洁、更好
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
q)`a`b`c#`a`c!1 2
a| 1
b|
c| 2