作者:张晓和46872 | 来源:互联网 | 2022-12-02 16:55
我是kdb/q的新手,我正在试图找出这个特定查询的含义.代码使用功能选择,我不太满意.
?[output;();b;a];
其中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)
为了完整起见,字典a
被定义为
volume ("sum";`size)
实际上,功能选择似乎将数据分成5分钟的桶并进行一些解析symbol
.令我困惑的是如何阅读groupby字典.特别是k)"
部分和整个事物都在引号中.有人可以帮助我解决这个问题,还是指出可以帮助我理解的资源?任何输入将不胜感激.
1> Mark Kelly..:
函数形式的聚合部分采用字典,键是输出键列名,值是解析树函数.
解析树是不立即求值的表达式.作为函数的第一个参数和后续元素是它的参数.首先评估最内部的括号,然后沿着层次向上移动,依次评估每个括号.可以在此处以及该页面上链接的白皮书中找到更详细的信息
您可以使用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)
,它返回%:
时间列上应用的结果.我们可以看到这%:
是函数的kltime
q)ltime
%:
向上移动一个级别,下一个评估的函数是{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))
向上移动到整个表达式相当于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)
内部函数{`$(,/)("/" vs string x)}
将符号串起来,将其拆分为"/"字符,然后将其重新连接在一起,从而有效地删除斜杠
这"k"
是一个使用k解释器计算字符串的函数.
"k""{x'y}""
返回一个函数,它本身接受一个函数x
和一个参数,y
并修改函数以使用每个副本'
.这使得该功能x
单独应用于每个符号而不是作为整体的列.
这可以q
代替k 来实现,如下所示:
({x@'y};{`$(,/)("/" vs string x)};`symbol)
该函数{x@'y}
接受函数参数{`$(,/)("/" vs string x)}
和symbol
列,如前所述,但是我们必须使用@
q中的每个副词来对参数应用函数.
然后,聚合函数将应用于每个组.在您的情况下,该函数是一个简单的解析树,它将返回sum
每个组中的大小列,并调用输出列volume
a:enlist[`volume]!enlist (sum;`size)
很好的解释!两个注释:`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)}; \`符号)`