聚焦重要数据价值丨DolphinDB 降采样算法介绍

news2025/1/11 6:11:24

1. 绪论

在真实的业务场景中,时间序列数据具有以下特点:

  • 采集频率(秒级甚至毫秒级)高,导致数据量非常庞大。
  • 数据价值密度低。

对数据进行合理的降采样不仅极大地可以降低系统压力、节约存储成本,同时也可以帮助用户聚焦重要信息,提升数据价值。本教程将以要点感知算法为例介绍如何在 DolphinDB 自定义并应用算法降采样数据。

1.1 行业背景

在物联网用户场景中,有一个普遍的需求是需要查询某个采集点的全年(一季度、一个月)的数据并做展示分析。在展示时,如果显示所有数据,会有性能问题,特别是实时展示。同时,这个也不是必须的,因为只需要展示大概的趋势就足以达到决策要求,太多数据点反而可能模糊决策。以折线图为例,可视化场景中,当 x 轴的数据不断增多,对应 y 轴的数据量增多,体现在图上的折线就会变得越来越复杂,当数量达到一定程度,很难再通过图找到具体的某一个点所表述的真实值是什么,数据变得很拥挤。下图展示了 1 个包含 1 万个数据点的折线图:

为了能够看到图形的整体,我们就要隐藏一些点,仅展示那些能够代表其他的点,或者是创建能够代表这些点的新数据点,这就是降采样算法解决的问题。

1.2 业务挑战

总体而言,在上述物联网时序数据应用场景中,首先需要将数据存下来,再将一定时间跨度的数据进行可视化展示,或者是流计算实时推送数据进行展示,而不对数据进行降采样,会存在以下几个问题:

  • 存储成本:高采集频率、多采集点数据的存储成本极高
  • 数据展示:展示原始数据遭遇性能瓶颈,且大量噪声数据影响局部趋势
  • 数据价值:数据价值不与存储、展示成本成正比

2. 降采样算法概述

DolphinDB 已经内置实现了简单的降采样算法如最大值、最小值、平均值等,用户可以直接调用相应函数进行计算。上述降采样算法都是将多条数据用一个值进行表示,这种表示方法的优点是计算简单、快速,缺点是信息损失较大。除此之外,许多学者还提出了大量更为复杂、高级的降采样算法,适用于不同的场景。DolphinDB 的语言具有强大的编程能力,支持用户自定义实现复杂的降采样算法,本文接下来将以 PIP 算法为例,介绍其算法原理、DolphinDB 脚本实现,并且给出了案例脚本,用户可以在自己的 DolphinDB server 上直接运行该脚本。

3. PIP 算法

3.1 PIP 介绍

PIP(Perceptually Important Points)算法又叫要点感知算法,是一种时间序列聚合算法,其思路是:对于一个长度为 n 的时间序列数据,迭代地依据最大距离原则采样出 k 个数据点, k 是人为设置的降采样数据点数(k <= n)。PIP 算法的具体步骤如下(论文参考:https://sci-hub.se/10.1109/iscmi.2017.8279589 )

  • 第一步:采样出时间序列的第 1 个和最后 1 个样本放入降采样数据点集
  • 第二步:计算剩余未采样样本点到其邻接的 2 个要点构成的直线的距离
  • 第三步:采样出距离最大的样本点放入降采样数据点集
  • 第四步:重复第二步和第三步直到采样要点数达到 k 个

可以通过下面的演示图片,更直观的感受 PIP 算法的计算过程:

其中,上述点到直线的距离计算常用的是垂直距离(Vertical Distance),本文中的脚本实现也将采用该距离计算公式。对于点(x3,y3)到另外两点(x1,y1)、(x2,y2)所构成直线的距离的计算公式为

即为下图中蓝色虚线所示的距离:

3.2 脚本实现

DolphinDB 支持用户通过 defg 声明编写脚本实现自定义聚合函数,并且 rolling 等滑动窗口函数支持调用用户自定义的聚合函数进行滑动计算,因此 DolphinDB 天然支持用户自定义降采样算法进行滑动计算,以下代码为 PIP 算法的脚本实现:

defg PIP(X, Y){
    data = table(X as x, Y as y)
    rowTab = select x, y, rowNo(x) as rowNo from data
    n = size(X)
// k为每次滑动降采样的数据量,取值范围为 3~n(n 为滑动窗口大小) 
    k = 5  
    samples = 2
    result = string(X[0])+"_"+string(Y[0])
    indexList = [0,n-1]
    do{
        distanceVec = [0.0]
        for (i in 0..(size(indexList)-2)){
            start, end = indexList[i], indexList[i+1]
            x1, y1 = X[start], Y[start]
            x2, y2 = X[end], Y[end]
            a = (y1-y2)/(x1-x2)
            b = y1-a*x1
            distanceVec=join(distanceVec, abs(Y[(start+1): end] - (X[(start+1): end]*a + b)))
            distanceVec.append!(0)
        }
        distanceMax = distanceVec.max()
        tmp = table(rowTab, distanceVec as distance)
        nextPoint = select x, y, rowNo from tmp where distance = distanceMax
        result += ","+string(nextPoint.x[0])+"_"+string(nextPoint.y[0])
        indexList = indexList.append!(nextPoint.rowNo[0]).sort()
        samples = samples+1
    }while(samples < k)
    result += ","+string(X.last())+"_"+string(Y.last())
    return result
}

3.3 算法性能

PIP 算法的时间复杂度是 O(n2),得益于 DolphinDB 内置的向量化编程,我们可以将算法的时间复杂度降低为 O(n) ,极大地提升了算法的计算性能,在单机社区版的 DolphinDB 上将 1 千万条的时间序列数据降采样至 4 万条数据只需 1.4s,并且还可以通过多线程的方式进一步提升性能。

4. 案例演示

4.1 案例脚本

本案例将以 1000 万条的正弦波动数据为例,使用 PIP 算法进行降维并展示降维前后的可视化对比,用户可以在自己的 DolphinDB 环境上运行该案例的完整代码。

  • 清理环境
login('admin', '123456')
undef(all)
clearAllCache()
  • 自定义 PIP 算法函数及解析函数
// PIP 算法聚合函数
defg PIP(X, Y){
    data = table(X as x, Y as y)
    rowTab = select x, y, rowNo(x) as rowNo from data
    n = size(X)
// k 为每次滑动降采样的数据量,取值范围为 3~n(n 为滑动窗口大小) 
    k = 5  
    samples = 2
    result = string(X[0])+"_"+string(Y[0])
    indexList = [0,n-1]
    do{
        distanceVec = [0.0]
        for (i in 0..(size(indexList)-2)){
            start, end = indexList[i], indexList[i+1]
            x1, y1 = X[start], Y[start]
            x2, y2 = X[end], Y[end]
            a = (y1-y2)/(x1-x2)
            b = y1-a*x1
            distanceVec=join(distanceVec, abs(Y[(start+1): end] - (X[(start+1): end]*a + b)))
            distanceVec.append!(0)
        }
        distanceMax = distanceVec.max()
        tmp = table(rowTab, distanceVec as distance)
        nextPoint = select x, y, rowNo from tmp where distance = distanceMax
        result += ","+string(nextPoint.x[0])+"_"+string(nextPoint.y[0])
        indexList = indexList.append!(nextPoint.rowNo[0]).sort()
        samples = samples+1
    }while(samples < k)
    result += ","+string(X.last())+"_"+string(Y.last())
    return result
}

// 降采样结果解析函数
def strToTable(result){
    samplesPIP = keyedTable(`x`y, 1:0, `x`y, `DOUBLE`DOUBLE)
    for (res in result){
        windows = res.split(',')
        for (window in windows){
            row = window.split('_')
            samplesPIP.append!(table([double(row[0])] as x, [double(row[1])] as y))
        }
    }
    return samplesPIP.sortBy!(`x, 1)  
}
  • 模拟数据
// 模拟 1 千万条正弦数据,大小为 153 MB
X = (double(0..9999999)*pi/1000)
Y = sin(X)
  • 结合 rolling 函数进行滑动计算
// 调用 rolling 函数进行滑动窗口计算,每 1000 个点滑动 1 次,降采样到 10 个点
timer{pipResult = rolling(PIP, [X, Y], 1000, 999)}

// 解析降采样结果输出一张表
samplesPIP = strToTable(pipResult)

4.2 结果展示

DolphinDB 内置了画图函数 plot,用户可以在库内直接调用对数据进行可视化展示,接下来将调用 plot 函数可视化对比降采样前后数据。

  • 原始数据折线图:
plot(Y[0:10000], X[0:10000])

  • 降采样数据折线图:
plot(samplesPIP.y[0:100], samplesPIP.x[0:100])

可见,PIP 降采样算法可以完全保留数据的趋势信息。但在实际业务场景中,需结合实际业务场景合理设置滑动窗口大小及降采样点数。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/917966.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于Redhat8.5 部署zabbix5.4

仓库配置 本地源配置 mount /dev/sr0 /mnt //先挂载vim /etc/fatab //编辑挂载文件 以便于开机自动挂载/dev/sr0 /mnt iso9660 defaults 0 0mount -a 编辑yum 仓库 vim /etc/yum.repo.d/redhat.repo[BaseOS] namebaseos baseurlfile:///mnt/BaseOS gpgcheck0[AppS…

时空智友企业流程化管控系统文件上传漏洞

时空智友企业流程化管控系统文件上传漏洞 一、 产品简介二、 漏洞概述三、 影响范围四、 复现环境五、 漏洞复现小龙poc检测脚本测试连接 六、 修复建议 免责声明&#xff1a;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的…

Java“牵手”快手商品详情数据,根据商品ID获取快手商品详情数据接口,快手API接口申请指南

快手小店怎么查看宝贝详情 快手小店作为快手平台上的一个电商服务&#xff0c;让很多卖家可以方便地在快手上开设店铺&#xff0c;销售自己的商品。如果你是快手小店的卖家&#xff0c;你可能会想知道如何查看自己的宝贝详情&#xff0c;以便更好地管理自己的店铺。下面就让我…

2.文章复现《热电联产系统在区域综合能源系统中的定容选址研究》(附matlab程序)

0.代码链接 1.简述 光热发电是大规模利用太阳能的新兴方式&#xff0c;其储热系 统能够调节光热电站的出力特性&#xff0c;进而缓解光热电站并网带来的火电机组调峰问题。合理配置光热电站储热容量&#xff0c;能够 有效降低火电机组调峰成本。该文提出一种光热电站储热容 量配…

原生JS实现拾色器功能

没事儿干&#xff0c;写一个拾色器&#xff0c;原生 JS 实现&#xff0c;先看效果图&#xff1a; 一、写页面 <div class"circle"></div>.circle {width: 200px;height: 200px;border: 1px #999 solid;margin: 200px 0 0 200px;border-radius: 50%;back…

rust库学习-env_logger(actix-web添加彩色日志、rust添加彩色日志 )

文章目录 介绍actix-web启用彩色日志crate地址&json格式日志 我们在进行rust的web开发时&#xff0c;如果不指定日志&#xff0c;就不会有输出&#xff0c;非常不友好 这里我们使用env_logger进行日志打印 介绍 env_logger 需要配合 log 库使用, env_logger 是 Rust 社区…

23年5月软考电子版证书已上线!

首先恭喜一下&#xff0c;5月软考考试通过的小伙伴们&#xff0c;几个月的辛苦耕耘&#xff0c;终于得到了回报&#xff01;即日起&#xff0c;23年5月软考电子版证书已上线&#xff01;可以登录网址自行下载了&#xff01; 2023年5月软考电子版证书查询打印方法一&#xff1a…

USB Type-C端口集成式ESD静电保护方案 安全低成本

Type-C端口是根据USB3.x和USB4协议传输数据的&#xff0c;很容易受到电气过载&#xff08;EOS&#xff09;和静电放电&#xff08;ESD&#xff09;事件的影响。由于Type-C支持随意热插拔功能&#xff0c;其内部高集成度的芯片&#xff0c;更容易受到人体静电放电的伤害和损坏。…

【算法系列篇】二分查找——这还是你所知道的二分查找算法吗?

文章目录 前言什么是二分查找算法1.二分查找1.1 题目要求1.2 做题思路1.3 Java代码实现 2.在排序数组中查找元素的第一个和最后一个位置2.1 题目要求2.2 做题思路2.3 Java代码实现 3.搜索插入位置3.1 题目要求3.2 做题思路3.3 Java代码实现 4.x的平方根4.1 题目要求4.2 做题思路…

2023年中,量子计算产业现状——

2023年上半年&#xff0c;量子计算&#xff08;QC&#xff09;领域取得了一系列重要进展和突破&#xff0c;显示出量子计算技术的快速发展和商业应用的不断拓展。在iCV TAnk近期发表的一篇报告中&#xff0c;团队从制度进步、产业生态、投融资形势、总结与展望四个方面对量子计…

word文件怎么免费转换为pdf格式?

大家在编辑word文件的时候&#xff0c;可能需要进行格式的转换&#xff0c;比如将word转换为pdf格式这时候需要使用工具软件。接下来小编就给大家介绍word文件怎么免费转换为pdf格式&#xff0c;免费word转pdf格式的方法。 免费word转pdf格式的方法 我们需要在电脑中安装并打开…

PySide6学习笔记--gui小模版使用

一、界面绘制 1.desiner画图 2.画图代码 # -*- coding: utf-8 -*-################################################################################ ## Form generated from reading UI file t1gui.ui ## ## Created by: Qt User Interface Compiler version 6.5.2 ## ##…

Ajax+Vue+ElementUI

文章目录 1.Ajax1.1 介绍1.2 Ajax快速入门1.3 案例-用户注册时&#xff0c;检测用户名是否数据库已经存在1.4 Axios1.4.1 Axios快速入门1.4.2 请求别名 1.5 JSON1.5.1 Json的基础语法1.5.2 FastJson的使用5.3.2 Fastjson 使用 2. Vue2.1 介绍2.2 Vue快速入门2.3 Vue常用指令和生…

el-upload 图片上传

1、这三个是必须的 2、设置对应的参数 3、设置上传之前和成功之后的回调

动态数据源切换类AbstractRoutingDataSource

写在前面 在工作中为了能够提高数据库的读写能力&#xff0c;经常会用到分库分表等技术&#xff0c;此时不可避免的就要涉及到动态数据源切换的内容&#xff0c;针对这个问题&#xff0c;spring提供了AbstractRoutingDataSource类来满足我们的需求&#xff0c;本文就一起来看下…

AI智能问答在哪些领域可以应用呢

对于AI智能问答这个全新的领域很多人都是懵懵懂懂的&#xff0c;以为这就和一些科技大企业有关。但是其实不是的&#xff0c;这和我们每个人的日常生活都息息相关。这篇文章&#xff0c;looklook就来和大家讲讲AI智能问答可以有哪些应用的方向&#xff0c;有需要的朋友们就看下…

F#奇妙游(22):Monte Carlo方法的F#实现

一个小问题的求解 问题 一根 1m 长的玻璃棒&#xff0c;摔倒地上断成 3 段&#xff0c;最短一段的平均值是多少&#xff1f; 假设玻璃棒一定会摔成三段&#xff0c;且玻璃棒质地均匀&#xff0c;为理想状态。 物理的视角 玻璃棒摔成三段&#xff0c;其物理过程是什么样的&…

VUE调用高德地图之电子围栏

最近项目上电子围栏功能,就是地图上限定的区域内实现限行功能,用我们身边的事物来举例,共享单车的限行、限停区域就是电子围栏。由此可见,电子围栏最基础的做法就是在地图上实现多边形覆盖物。 效果图大概如下: 照例,第一步:加载JS AP。 1.在public/index.html中加入…

【LINUX协议栈】netfilter之连接跟踪机制

1、什么是链接跟踪 连接跟踪&#xff0c;顾名思义&#xff0c;就是跟踪&#xff08;并记录&#xff09;连接的状态。一般conntrack用来指代“Connection Tracking”&#xff0c;即连接跟踪&#xff0c;是建立在 Netfilter框架之上的重要功能之一。 2、为什么需要链路跟踪 因…

天润融通「微藤大语言模型平台2.0」以知识驱动企业高速增长

8月23日&#xff0c;天润融通&#xff08;又称“天润云”,2167.HK&#xff09;&#xff0c;正式发布「微藤大语言模型平台2.0」。 “大模型企业知识企业知识工程”。 “不能有效记录和管理知识的企业是不能持续进步的。在企业的生产流程中&#xff0c;相比于其他场景&#xff0…