kdb/q问题:我如何在功能选择中解释这个组?

Byn*_*yng 1 group-by kdb

我是kdb/q的新手,我正在试图找出这个特定查询的含义.代码使用功能选择,我不太满意.

?[output;();b;a];
Run Code Online (Sandbox Code Playgroud)

其中output是一些包含列的表 size time symbol

groupby过滤字典b定义如下

key | value
---------------
ts  | ("+";00:05:00v;("k){x*y div x:$[16h=abs[@x];"j"$x;x]}";00:05:00v;("%:";`time)))
sym | ("k){x'y}";"{`$(,/)("/" vs string x)}";`symbol)
Run Code Online (Sandbox Code Playgroud)

为了完整起见,字典a被定义为

volume  ("sum";`size)  
Run Code Online (Sandbox Code Playgroud)

实际上,功能选择似乎将数据分成5分钟的桶并进行一些解析symbol.令我困惑的是如何阅读groupby字典.特别是k)"部分和整个事物都在引号中.有人可以帮助我解决这个问题,还是指出可以帮助我理解的资源?任何输入将不胜感激.

Mar*_*lly 5

函数形式的聚合部分采用字典,键是输出键列名,值是解析树函数.

解析树是不立即求值的表达式.作为函数的第一个参数和后续元素是它的参数.首先评估最内部的括号,然后沿着层次向上移动,依次评估每个括号.可以在此处以及该页面上链接的白皮书中找到更详细的信息

您可以使用parse带有字符串参数的函数来获取函数的解析树.例如,解析树1+2+3(+;1;(+;2;3)):

q)parse "1+2+3"
+
1
(+;2;3)
Run Code Online (Sandbox Code Playgroud)

在结果被传播到最外部的解析树函数给出之前,(+;2;3)首先评估最内部括号5(+;1;5)6

该子句的groupby部分将评估一个或多个解析树函数,然后将收集来自分组函数的相同输出的记录.

使函数更清晰易读:

(+;00:05:00v;({x*y div x:$[16h=abs[@x];"j"$x;x]}";00:05:00v;(%:;`time)))
Run Code Online (Sandbox Code Playgroud)

查看最内部括号(%:;`time),它返回%:时间列上应用的结果.我们可以看到这%:是函数的kltime

q)ltime
%:
Run Code Online (Sandbox Code Playgroud)

向上移动一个级别,下一个评估的函数是{x*y div x:$[16h=abs[@x];"j"$x;x]}带有参数的lambda函数00:05:00v和我们之前评估函数的结果.lambda将它向下舍入最近的5分钟间隔

({x*y div x:$[16h=abs[@x];"j"$x;x]};00:05:00v;(%:;`time))
Run Code Online (Sandbox Code Playgroud)

向上移动到整个表达式相当于00:05:00v + {x*y div x:$[16h=abs[@x];"j"$x;x]};00:05:00v;(%:;`time)),将00:05:00添加到先前评估的每个结果上.

所以基本上它首先返回时间戳的本地时间,然后

用于symbol聚合

("k""{x'y}";{`$(,/)("/" vs string x)};`symbol)
Run Code Online (Sandbox Code Playgroud)

内部函数{`$(,/)("/" vs string x)}将符号串起来,将其拆分为"/"字符,然后将其重新连接在一起,从而有效地删除斜杠

"k"是一个使用k解释器计算字符串的函数.

"k""{x'y}""返回一个函数,它本身接受一个函数x和一个参数,y并修改函数以使用每个副本'.这使得该功能x单独应用于每个符号而不是作为整体的列.

这可以q代替k 来实现,如下所示:

({x@'y};{`$(,/)("/" vs string x)};`symbol)
Run Code Online (Sandbox Code Playgroud)

该函数{x@'y}接受函数参数{`$(,/)("/" vs string x)}symbol 列,如前所述,但是我们必须使用@q中的每个副词来对参数应用函数.

然后,聚合函数将应用于每个组.在您的情况下,该函数是一个简单的解析树,它将返回sum每个组中的大小列,并调用输出列volume

a:enlist[`volume]!enlist (sum;`size)
Run Code Online (Sandbox Code Playgroud)

  • 很好的解释!两个注释:`k){x*y div x:$ [16h = abs [@x];"j"$ x; x]}`是`xbar`和`k){x'y}`是`每个`所以对q最简单的翻译是`(xbar; 00:05:00v;(ltime; \`time))`和`(每个; {\`$(,/)("/"vs string x)}; \`符号)` (2认同)