高阶函数
介绍
DolphinDB内置的高阶函数,可以扩展或增强函数或者运算符的功能。高阶函数以一个函数与数据对象作为输入内容,类似于一个函数和数据之间的管道。通常,输入数据首先以一种预设的方式被分解成多个数据块(可能重叠),然后将函数应用于每个数据块,最后将所有的结果组合为一个对象返回。高阶函数的输入数据可以是向量、矩阵或者表,也可以是标量或字典。通过使用高阶函数,某些复杂的分析任务可以用几行代码就可以高效地完成。
语法
高阶函数总是与运算符、用户自定义函数或者系统函数共同使用。所有的高阶函数符号以冒号开头,之后紧跟一个大写字母。
higherOrderFunctionName (<functionName>, functionParameter1, …functionParameterN)
或
<functionName> :<higher order symbol> functionParameter
或
functionParameter1 <functionName> :<higher order symbol> functionParameter2
DolphinDB中,所有高阶函数的第一个参数必须是一个函数名,不可以是函数名数组。如果需要在同一个高阶函数中调用多个函数,可以指定该高阶函数的第一个参数为 call 高阶函数,然后在 call 的参数中指定多个函数,详情请见 call。
注意:从 1.30.17 版本开始,高阶函数的第一个参数会被强制解析为函数。
高阶函数总结
下面的表中,总结了高阶函数的名字和应用场景。
符号 |
函数名 |
应用范围 |
典型应用 |
---|---|---|---|
:E |
each |
二元运算符,一元运算符,函数调用 |
|
peach |
并行版本的each |
||
:R |
eachRight |
二元运算符 |
|
:L |
eachLeft |
二元运算符 |
|
:P |
eachPre |
二元运算符 |
|
:O |
eachPost |
二元运算符,函数调用 |
|
pivot |
函数调用 |
原始数据或分组聚合结果进行行列转置 |
|
:A |
accumulate |
二元运算符,函数调用 |
|
:T |
reduce |
二元运算符,函数调用 |
|
:G |
groupby |
函数调用,二元运算符 |
|
:C |
cross |
二元运算符,函数调用 |
|
pcross |
并行版本的cross |
||
moving |
函数调用(聚合函数),二元运算符 |
||
loop |
二元运算符,一元运算符,函数调用,混合返回类型 |
||
ploop |
并行版本的loop |
||
all |
二元运算符,函数调用 |
||
any |
二元运算符,函数调用 |
||
call |
二元运算符 |
通常与each函数配合使用,实现同时调用一批函数 |
|
pcall |
并行版本的call |
||
:X |
contextby |
函数调用,二元运算符 |
分组内进行指定的计算 |
segmentby |
函数调用,二元运算符 |
||
rolling |
函数调用,二元运算符 |
计算APPL相对于市场(SPY)的beta值 |
|
withNullFill |
二元运算符 |
使用特定值替换Null值参与计算 |
|
byRow |
函数调用 |
矩阵按行计算 |
上表中的符号可以迭代使用,按从左到右顺序执行符号对应的分解操作,将分解后的数据块应用于函数或操作符,最后将各子任务的结果组合为一个对象并返回。 比如 X <operator> :E:L Y,先对 X 和 Y 执行 :E 对应的分解(拆解为 X(i), Y(i)),再执行 :L 对应的分解操作后作用于操作符, 即对每一个 X(i) 执行了 X(i) <operator>:L Y(i),最后组合各个子任务的结果并输出。具体例子如下:
$ a=1 2 3
$ b=4 5 6
$ c=(a,b)
$ re=c +:E:L c
$ re
(1 2 3
- - -
2 3 4
3 4 5
4 5 6
,4 5 6
-- -- --
8 9 10
9 10 11
10 11 12
)
分解和组装规则
通常来说,一个向量被分解成多个标量,一个 tuple 被拆分出各个元素(各元素的形式不同),一个矩阵被分解成多列(向量),一个表或字典被分解成多行(字典)。
在组装阶段,标量类型合并组成一个向量,向量合并成一个矩阵,字典合并成一张表,其它情况(数据形式不一致时)合并成一个元组。
高阶函数按元素遍历向量/tuple,按列遍历矩阵,按行遍历表或字典。