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

kdb/q question: How do I interpret this groupby in my functional selection?

我是 kdb/q 的新手,我想弄清楚这个特定查询的含义。该代码使用的是函数式 select,我对此并不太满意 table。

?[output;();b;a];

其中输出是一些 table,其中包含列 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)

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

volume  ("sum";`size)  

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

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

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

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

q)parse "1+2+3"
+
1
(+;2;3)

首先计算最内层的括号 (+;2;3),结果为 5,然后将结果传播到最外层的解析树函数 (+;1;5),给出 6

该子句的 groupby 部分将评估一个或多个解析树函数,然后将具有相同分组函数输出的记录收集在一起。

使函数更易读:

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

查看最里面的括号 (%:;`time),它 return 是 %: 应用于时间列的结果。我们可以看到 %: 是函数 ltime

的 k
q)ltime
%:

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

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

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

所以本质上它首先是 return 时间戳的本地时间,然后是

对于symbol聚合

("k""{x'y}";{`$(,/)("/" vs string x)};`symbol)

内部函数{`$(,/)("/" vs string x)}串一个符号,在“/”字符处将其拆分,然后将其重新组合在一起,有效地删除了斜线

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

"k""{x'y}"" returns 是一个函数,它本身接受函数 x 和参数 y 并修改函数以使用 each-both 副词 ' .这使得函数 x 单独应用于每个符号而不是整个列。

这可以在 q 中实现,而不是像这样在 k 中实现:

({x@'y};{`$(,/)("/" vs string x)};`symbol)

函数{x@'y}像以前一样采用函数参数{`$(,/)("/" vs string x)}symbol列,但我们必须在q中使用@和each-both副词将函数应用于参数。

聚合函数随后将应用于每个组。在您的情况下,该函数是一个简单的解析树,它将 return 每个组中大小列的 sum ,输出列称为 volume

a:enlist[`volume]!enlist (sum;`size)