DolphinDB自定义函数:UDF开发指南

目录

    • 摘要
    • 一、自定义函数概述
      • [1.1 什么是自定义函数](#1.1 什么是自定义函数)
      • [1.2 自定义函数优势](#1.2 自定义函数优势)
    • 二、函数定义
      • [2.1 基本语法](#2.1 基本语法)
      • [2.2 无返回值函数](#2.2 无返回值函数)
      • [2.3 多返回值函数](#2.3 多返回值函数)
    • 三、参数传递
      • [3.1 位置参数](#3.1 位置参数)
      • [3.2 默认参数](#3.2 默认参数)
      • [3.3 可变参数](#3.3 可变参数)
      • [3.4 字典参数](#3.4 字典参数)
    • 四、作用域
      • [4.1 局部变量](#4.1 局部变量)
      • [4.2 全局变量](#4.2 全局变量)
      • [4.3 变量优先级](#4.3 变量优先级)
    • 五、递归函数
      • [5.1 递归基础](#5.1 递归基础)
      • [5.2 斐波那契数列](#5.2 斐波那契数列)
      • [5.3 尾递归优化](#5.3 尾递归优化)
    • 六、高阶函数
      • [6.1 函数作为参数](#6.1 函数作为参数)
      • [6.2 匿名函数](#6.2 匿名函数)
      • [6.3 内置高阶函数](#6.3 内置高阶函数)
    • 七、函数进阶
      • [7.1 闭包](#7.1 闭包)
      • [7.2 函数缓存](#7.2 函数缓存)
      • [7.3 函数组合](#7.3 函数组合)
    • 八、实战案例
      • [8.1 数据处理工具函数](#8.1 数据处理工具函数)
      • [8.2 工业计算函数](#8.2 工业计算函数)
    • 九、总结
    • 参考资料

摘要

本文深入讲解DolphinDB自定义函数开发。从函数定义到参数传递,从返回值到作用域,从递归函数到高阶函数,全面介绍UDF开发的核心方法。通过丰富的代码示例,帮助读者掌握自定义函数开发的核心技能。


一、自定义函数概述

1.1 什么是自定义函数

自定义函数(UDF)是用户根据业务需求编写的函数:
#mermaid-svg-2EyY4Fa8A2lJP96m{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-2EyY4Fa8A2lJP96m .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-2EyY4Fa8A2lJP96m .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-2EyY4Fa8A2lJP96m .error-icon{fill:#552222;}#mermaid-svg-2EyY4Fa8A2lJP96m .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-2EyY4Fa8A2lJP96m .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-2EyY4Fa8A2lJP96m .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-2EyY4Fa8A2lJP96m .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-2EyY4Fa8A2lJP96m .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-2EyY4Fa8A2lJP96m .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-2EyY4Fa8A2lJP96m .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-2EyY4Fa8A2lJP96m .marker{fill:#333333;stroke:#333333;}#mermaid-svg-2EyY4Fa8A2lJP96m .marker.cross{stroke:#333333;}#mermaid-svg-2EyY4Fa8A2lJP96m svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-2EyY4Fa8A2lJP96m p{margin:0;}#mermaid-svg-2EyY4Fa8A2lJP96m .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-2EyY4Fa8A2lJP96m .cluster-label text{fill:#333;}#mermaid-svg-2EyY4Fa8A2lJP96m .cluster-label span{color:#333;}#mermaid-svg-2EyY4Fa8A2lJP96m .cluster-label span p{background-color:transparent;}#mermaid-svg-2EyY4Fa8A2lJP96m .label text,#mermaid-svg-2EyY4Fa8A2lJP96m span{fill:#333;color:#333;}#mermaid-svg-2EyY4Fa8A2lJP96m .node rect,#mermaid-svg-2EyY4Fa8A2lJP96m .node circle,#mermaid-svg-2EyY4Fa8A2lJP96m .node ellipse,#mermaid-svg-2EyY4Fa8A2lJP96m .node polygon,#mermaid-svg-2EyY4Fa8A2lJP96m .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-2EyY4Fa8A2lJP96m .rough-node .label text,#mermaid-svg-2EyY4Fa8A2lJP96m .node .label text,#mermaid-svg-2EyY4Fa8A2lJP96m .image-shape .label,#mermaid-svg-2EyY4Fa8A2lJP96m .icon-shape .label{text-anchor:middle;}#mermaid-svg-2EyY4Fa8A2lJP96m .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-2EyY4Fa8A2lJP96m .rough-node .label,#mermaid-svg-2EyY4Fa8A2lJP96m .node .label,#mermaid-svg-2EyY4Fa8A2lJP96m .image-shape .label,#mermaid-svg-2EyY4Fa8A2lJP96m .icon-shape .label{text-align:center;}#mermaid-svg-2EyY4Fa8A2lJP96m .node.clickable{cursor:pointer;}#mermaid-svg-2EyY4Fa8A2lJP96m .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-2EyY4Fa8A2lJP96m .arrowheadPath{fill:#333333;}#mermaid-svg-2EyY4Fa8A2lJP96m .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-2EyY4Fa8A2lJP96m .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-2EyY4Fa8A2lJP96m .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-2EyY4Fa8A2lJP96m .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-2EyY4Fa8A2lJP96m .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-2EyY4Fa8A2lJP96m .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-2EyY4Fa8A2lJP96m .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-2EyY4Fa8A2lJP96m .cluster text{fill:#333;}#mermaid-svg-2EyY4Fa8A2lJP96m .cluster span{color:#333;}#mermaid-svg-2EyY4Fa8A2lJP96m div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-2EyY4Fa8A2lJP96m .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-2EyY4Fa8A2lJP96m rect.text{fill:none;stroke-width:0;}#mermaid-svg-2EyY4Fa8A2lJP96m .icon-shape,#mermaid-svg-2EyY4Fa8A2lJP96m .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-2EyY4Fa8A2lJP96m .icon-shape p,#mermaid-svg-2EyY4Fa8A2lJP96m .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-2EyY4Fa8A2lJP96m .icon-shape .label rect,#mermaid-svg-2EyY4Fa8A2lJP96m .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-2EyY4Fa8A2lJP96m .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-2EyY4Fa8A2lJP96m .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-2EyY4Fa8A2lJP96m :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 自定义函数
函数定义
参数传递
函数体执行
返回结果
函数类型
标量函数
聚合函数
高阶函数

1.2 自定义函数优势

优势 说明
代码复用 避免重复代码
模块化 逻辑清晰易维护
可扩展 灵活扩展功能
性能优化 向量化计算

二、函数定义

2.1 基本语法

python 复制代码
// 基本函数定义
def functionName(param1, param2, ...) {
    // 函数体
    return result
}

// 示例:计算两数之和
def add(a, b) {
    return a + b
}

// 调用函数
add(1, 2)  // 返回 3

2.2 无返回值函数

python 复制代码
// 无返回值函数
def printInfo(name, value) {
    print("名称: " + name + ", 值: " + string(value))
}

// 调用
printInfo("温度", 25.5)  // 输出: 名称: 温度, 值: 25.5

2.3 多返回值函数

python 复制代码
// 多返回值函数
def getStats(data) {
    return avg(data), max(data), min(data)
}

// 调用
avgVal, maxVal, minVal = getStats([1, 2, 3, 4, 5])
print("平均值: " + string(avgVal))  // 3
print("最大值: " + string(maxVal))  // 5
print("最小值: " + string(minVal))  // 1

三、参数传递

3.1 位置参数

python 复制代码
// 位置参数:按顺序传递
def createPoint(x, y, z) {
    return [x, y, z]
}

createPoint(1, 2, 3)  // [1, 2, 3]

3.2 默认参数

python 复制代码
// 默认参数
def greet(name, greeting = "你好") {
    return greeting + ", " + name + "!"
}

greet("张三")           // "你好, 张三!"
greet("张三", "欢迎")   // "欢迎, 张三!"

3.3 可变参数

python 复制代码
// 可变参数
def sumAll(nums...) {
    total = 0
    for (n in nums) {
        total += n
    }
    return total
}

sumAll(1, 2, 3)       // 6
sumAll(1, 2, 3, 4, 5) // 15

3.4 字典参数

python 复制代码
// 字典参数
def processConfig(config) {
    return config
}

processConfig(dict(STRING, ANY, [
    ["host", "localhost"],
    ["port", 8848],
    ["debug", true]
]))

四、作用域

4.1 局部变量

python 复制代码
// 局部变量:函数内部定义
def calculate(x) {
    localVar = x * 2  // 局部变量
    return localVar
}

calculate(5)  // 10
// localVar  // 错误:外部无法访问

4.2 全局变量

python 复制代码
// 全局变量
globalVar = 100

def useGlobal() {
    return globalVar  // 可以访问全局变量
}

useGlobal()  // 100

4.3 变量优先级

python 复制代码
// 变量优先级:局部 > 全局
value = 10  // 全局变量

def test() {
    value = 20  // 局部变量
    return value
}

test()     // 20(局部变量)
value      // 10(全局变量)

五、递归函数

5.1 递归基础

python 复制代码
// 递归:阶乘
def factorial(n) {
    if (n <= 1) return 1
    return n * factorial(n - 1)
}

factorial(5)  // 120
factorial(10) // 3628800

5.2 斐波那契数列

python 复制代码
// 斐波那契数列
def fibonacci(n) {
    if (n <= 0) return 0
    if (n == 1) return 1
    return fibonacci(n - 1) + fibonacci(n - 2)
}

fibonacci(10)  // 55

5.3 尾递归优化

python 复制代码
// 尾递归优化
def factorialTail(n, acc = 1) {
    if (n <= 1) return acc
    return factorialTail(n - 1, n * acc)
}

factorialTail(100)  // 支持大数计算

六、高阶函数

6.1 函数作为参数

python 复制代码
// 函数作为参数
def apply(func, x) {
    return func(x)
}

def double(x) { return x * 2 }
def square(x) { return x * x }

apply(double, 5)  // 10
apply(square, 5)  // 25

6.2 匿名函数

python 复制代码
// 匿名函数(Lambda)
def applyLambda(func, x) {
    return func(x)
}

applyLambda(def(x) { return x * 3 }, 5)  // 15

6.3 内置高阶函数

python 复制代码
// each:对每个元素应用函数
each(def(x) { return x * 2 }, [1, 2, 3, 4, 5])
// [2, 4, 6, 8, 10]

// map:映射
map(def(x) { return x * x }, [1, 2, 3, 4, 5])
// [1, 4, 9, 16, 25]

// filter:过滤
filter(def(x) { return x > 2 }, [1, 2, 3, 4, 5])
// [3, 4, 5]

// reduce:归约
reduce(def(x, y) { return x + y }, [1, 2, 3, 4, 5])
// 15

七、函数进阶

7.1 闭包

python 复制代码
// 闭包
def makeCounter() {
    count = 0
    return def() {
        count += 1
        return count
    }
}

counter = makeCounter()
counter()  // 1
counter()  // 2
counter()  // 3

7.2 函数缓存

python 复制代码
// 函数缓存(记忆化)
def memoize(func) {
    cache = dict()
    return def(x) {
        if (cache.has(x)) {
            return cache[x]
        }
        result = func(x)
        cache[x] = result
        return result
    }
}

// 缓存斐波那契
fibMemo = memoize(def(n) {
    if (n <= 0) return 0
    if (n == 1) return 1
    return fibMemo(n - 1) + fibMemo(n - 2)
})

fibMemo(50)  // 快速计算

7.3 函数组合

python 复制代码
// 函数组合
def compose(f, g) {
    return def(x) {
        return f(g(x))
    }
}

double = def(x) { return x * 2 }
square = def(x) { return x * x }

doubleThenSquare = compose(square, double)
doubleThenSquare(3)  // (3 * 2)^2 = 36

八、实战案例

8.1 数据处理工具函数

python 复制代码
// ========== 数据处理工具函数库 ==========

// 数据标准化
def normalize(data) {
    minVal = min(data)
    maxVal = max(data)
    return (data - minVal) / (maxVal - minVal)
}

// Z-Score标准化
def zscore(data) {
    meanVal = avg(data)
    stdVal = std(data)
    return (data - meanVal) / stdVal
}

// 滑动平均
def movingAverage(data, window) {
    result = array(DOUBLE, data.size())
    for (i in 0..data.size()) {
        if (i < window - 1) {
            result[i] = NULL
        } else {
            result[i] = avg(data[(i-window+1):(i+1)])
        }
    }
    return result
}

// 异常值检测
def detectOutliers(data, threshold = 3) {
    meanVal = avg(data)
    stdVal = std(data)
    return abs(data - meanVal) > threshold * stdVal
}

// 测试
data = [1, 2, 3, 4, 5, 100, 6, 7, 8, 9]
normalize(data)
zscore(data)
detectOutliers(data)

8.2 工业计算函数

python 复制代码
// ========== 工业计算函数库 ==========

// 温度单位转换
def celsiusToFahrenheit(celsius) {
    return celsius * 1.8 + 32
}

def fahrenheitToCelsius(fahrenheit) {
    return (fahrenheit - 32) / 1.8
}

// 压力单位转换
def barToPsi(bar) {
    return bar * 14.5038
}

def psiToBar(psi) {
    return psi / 14.5038
}

// 流量计算
def calculateFlow(velocity, area) {
    return velocity * area
}

// 能耗计算
def calculateEnergy(power, hours) {
    return power * hours  // kWh
}

// OEE计算
def calculateOEE(availability, performance, quality) {
    return availability * performance * quality * 100
}

// 测试
celsiusToFahrenheit(25)    // 77
calculateOEE(0.9, 0.85, 0.95)  // 72.675

九、总结

本文详细介绍了DolphinDB自定义函数开发:

  1. 函数定义:基本语法、返回值
  2. 参数传递:位置参数、默认参数、可变参数
  3. 作用域:局部变量、全局变量
  4. 递归函数:阶乘、斐波那契、尾递归
  5. 高阶函数:函数参数、匿名函数、内置高阶函数
  6. 函数进阶:闭包、缓存、组合

思考题

  1. 如何设计可复用的函数?
  2. 递归和循环如何选择?
  3. 高阶函数有什么应用场景?

参考资料


相关推荐
weixin199701080161 小时前
[特殊字符] 电商库存扣减防超卖:分布式锁的三种实现(附Python源码)
开发语言·分布式·python
z落落1 小时前
C# 多态 + 函数重载(静态多态)+运算符重载
开发语言·c#
长和信泰光伏储能1 小时前
北京光伏方案解析:探索绿色能源新趋势
python·能源
码不停蹄的玄黓1 小时前
Java 应用 CPU 过高排查全流程
java·开发语言·python
许彰午1 小时前
11_Java集合框架概述
java·windows·python
好好风格1 小时前
微软这个 14 万星工具,把 PDF、PPT、Excel 都变成大模型爱读的 Markdown
人工智能·python·开源
小糖学代码1 小时前
机器学习:1.机器学习基本概念
人工智能·python·机器学习
甄心爱学习1 小时前
【项目实训】法律文书智能摘要系统7
git·python
SiYuanFeng1 小时前
大厂面试python复习基础100题
python·面试·职场和发展