一文掌握 DuckDB 时间序列分析:窗口函数实战详解
wptr33 2025-07-28 00:38 29 浏览
uckDB 支持基于时间的窗口分析,包括固定窗口(tumbling)、跳跃窗口(hopping)和滑动窗口(sliding)等不同语义的窗口函数。在本文中,我们将通过实际案例 —— 对阿姆斯特丹中央车站的列车运行数据进行趋势和异常检测 —— 来演示这些窗口函数的使用方式。
引言:为什么时间窗口分析很重要?
在数据平台中,我们通常将数据分为两类:维度数据(Dimension)和事实数据(Fact)。维度数据描述的是实体信息,例如名称、地址、序列号等;而事实数据则代表与这些实体相关的事件,比如点击、销售记录、银行交易、IoT 设备读取值等。
事实数据往往包含时间戳(timestamp)字段,用于标识事件发生或被观察到的时间。在流处理平台中,带时间戳的数据通常需要通过流式窗口函数来划分时间片段,以便进行有序计算。
但在实际分析中,我们也经常希望对静态的时间戳数据应用类似的窗口划分逻辑,以提取出趋势、汇总和异常。本文将基于 DuckDB 展示如何使用流式窗口函数对阿姆斯特丹中央车站的列车服务数据进行时间分析,识别高峰时段、服务中断等关键指标。
在本文的实现中,我们将使用一个已建立的 DuckDB 数据库。该项目基于“Rijden de Treinen”(火车运行了吗?)应用的开放数据。
我们首先在任意 DuckDB 会话中,挂载存储位置中的该数据库:
固定窗口(Tumbling Windows)
固定窗口是具有固定大小的时间区间,格式为左闭右开区间 [left-closed, right-open),用于在某个时间单位(如年、日、小时等)上计算汇总信息。
固定窗口还常用于将(不规则的)事实数据转化为时间序列数据,通过在固定时间间隔内进行聚合实现这一目的。
实现固定窗口的一种方式是使用 date_trunc 函数,该函数会将时间戳截断到指定的精度。
例如,在下面的示例中,我们统计了 2024 年中每小时和每天的列车服务次数:
另一种方法是使用time_bucket函数,该函数将从指定的偏移量开始,将时间戳截断为指定的桶宽度。例如,我们计算每刻钟的服务数量,从以下位置开始00:
跳跃窗口(Hopping Windows)
跳跃窗口是固定大小的时间间隔,但与滚动窗口相反,跳跃窗口是重叠的。跳跃窗口的定义如下:
- 窗口开始时间之间应经过多少时间,称为跳跃大小;
- 一个窗口应该包含多少时间,称为窗口大小。
跳跃窗口的一个用例是确定 2024 年内最繁忙的五个 15 分钟时段(窗口大小),每 5 分钟(跳跃大小)开始一次。我们首先为所有感兴趣的日期生成人工跳跃窗口:
然后,我们将上述间隔与火车服务数据结合起来,以计算每个[左闭,右开]间隔的服务数量:
滑动窗口(Sliding Windows)
滑动窗口是重叠的区间,但与跳跃窗口相比,滑动窗口是根据所分析的时间列动态生成的,因此会在插入新记录时发生变化。滑动窗口可以通过使用RANGE窗口框架来实现:
会话窗口(Session Windows)
会话窗口将时间上相近发生的事件分组,并以不活动间隙分隔。当两个事件之间的时间间隔超过定义的超时值时,将启动新的会话。会话窗口最常见的用例是检测带时间戳的数据中的间隙。
我们继续进行数据分析,找出阿姆斯特丹中央火车站没有列车到达/出发的时间段超过10分钟的日期。在此上下文中,会话窗口是指列车服务运行且服务停顿间隔不超过10分钟的时间段。
lag我们首先使用窗口函数计算每条记录的上一次服务时间。我们上面观察到,夜间几乎没有交通,因此我们只包括上午 6 点到晚上 11 点之间的服务:
在上面的查询中,我们还计算了当前服务与上一次服务之间的间隔(以分钟为单位),其中date_diff。如果没有上一次服务,则该列将为0,表示当天的第一次服务会话.
然后,我们通过将经过的分钟数与超时时间(在我们的例子中为 10 分钟)进行比较,标记当前记录是否与前一个记录位于同一会话中:
通过对属性应用日级移动总和,new_session我们为会话分配一个标识符:
我们现在可以检索在 18 小时服务时间(上午 6 点到晚上 11 点之间的小时数)内至少有 10 分钟不活动间隔的日期:
2024年4月29日肯定异情况!我们观察到,在18个小时的运营期间,出现了12个时段窗口,这意味着至少有10次,在10分钟内没有列车到达或出发。原因可能是当天没有常规列车服务。而且,阿姆斯特丹和乌得勒支之间确实开始了维护工作。
上述内容演示了如何在 DuckDB 中对带时间戳的历史数据实现流窗口函数,为时间(序列)数据分析提供了一个起点。
相关推荐
- oracle数据导入导出_oracle数据导入导出工具
-
关于oracle的数据导入导出,这个功能的使用场景,一般是换服务环境,把原先的oracle数据导入到另外一台oracle数据库,或者导出备份使用。只不过oracle的导入导出命令不好记忆,稍稍有点复杂...
- 继续学习Python中的while true/break语句
-
上次讲到if语句的用法,大家在微信公众号问了小编很多问题,那么小编在这几种解决一下,1.else和elif是子模块,不能单独使用2.一个if语句中可以包括很多个elif语句,但结尾只能有一个...
- python continue和break的区别_python中break语句和continue语句的区别
-
python中循环语句经常会使用continue和break,那么这2者的区别是?continue是跳出本次循环,进行下一次循环;break是跳出整个循环;例如:...
- 简单学Python——关键字6——break和continue
-
Python退出循环,有break语句和continue语句两种实现方式。break语句和continue语句的区别:break语句作用是终止循环。continue语句作用是跳出本轮循环,继续下一次循...
- 2-1,0基础学Python之 break退出循环、 continue继续循环 多重循
-
用for循环或者while循环时,如果要在循环体内直接退出循环,可以使用break语句。比如计算1至100的整数和,我们用while来实现:sum=0x=1whileTrue...
- Python 中 break 和 continue 傻傻分不清
-
大家好啊,我是大田。...
- python中的流程控制语句:continue、break 和 return使用方法
-
Python中,continue、break和return是控制流程的关键语句,用于在循环或函数中提前退出或跳过某些操作。它们的用途和区别如下:1.continue(跳过当前循环的剩余部分,进...
- L017:continue和break - 教程文案
-
continue和break在Python中,continue和break是用于控制循环(如for和while)执行流程的关键字,它们的作用如下:1.continue:跳过当前迭代,...
- 作为前端开发者,你都经历过怎样的面试?
-
已经裸辞1个月了,最近开始投简历找工作,遇到各种各样的面试,今天分享一下。其实在职的时候也做过面试官,面试官时,感觉自己问的问题很难区分候选人的能力,最好的办法就是看看候选人的github上的代码仓库...
- 面试被问 const 是否不可变?这样回答才显功底
-
作为前端开发者,我在学习ES6特性时,总被const的"善变"搞得一头雾水——为什么用const声明的数组还能push元素?为什么基本类型赋值就会报错?直到翻遍MDN文档、对着内存图反...
- 2023金九银十必看前端面试题!2w字精品!
-
导文2023金九银十必看前端面试题!金九银十黄金期来了想要跳槽的小伙伴快来看啊CSS1.请解释CSS的盒模型是什么,并描述其组成部分。...
- 前端面试总结_前端面试题整理
-
记得当时大二的时候,看到实验室的学长学姐忙于各种春招,有些收获了大厂offer,有些还在苦苦面试,其实那时候的心里还蛮忐忑的,不知道自己大三的时候会是什么样的一个水平,所以从19年的寒假放完,大二下学...
- 由浅入深,66条JavaScript面试知识点(七)
-
作者:JakeZhang转发链接:https://juejin.im/post/5ef8377f6fb9a07e693a6061目录...
- 2024前端面试真题之—VUE篇_前端面试题vue2020及答案
-
添加图片注释,不超过140字(可选)...
- 今年最常见的前端面试题,你会做几道?
-
在面试或招聘前端开发人员时,期望、现实和需求之间总是存在着巨大差距。面试其实是一个交流想法的地方,挑战人们的思考方式,并客观地分析给定的问题。可以通过面试了解人们如何做出决策,了解一个人对技术和解决问...
- 一周热门
- 最近发表
-
- oracle数据导入导出_oracle数据导入导出工具
- 继续学习Python中的while true/break语句
- python continue和break的区别_python中break语句和continue语句的区别
- 简单学Python——关键字6——break和continue
- 2-1,0基础学Python之 break退出循环、 continue继续循环 多重循
- Python 中 break 和 continue 傻傻分不清
- python中的流程控制语句:continue、break 和 return使用方法
- L017:continue和break - 教程文案
- 作为前端开发者,你都经历过怎样的面试?
- 面试被问 const 是否不可变?这样回答才显功底
- 标签列表
-
- git pull (33)
- git fetch (35)
- mysql insert (35)
- mysql distinct (37)
- concat_ws (36)
- java continue (36)
- jenkins官网 (37)
- mysql 子查询 (37)
- python元组 (33)
- mybatis 分页 (35)
- vba split (37)
- redis watch (34)
- python list sort (37)
- nvarchar2 (34)
- mysql not null (36)
- hmset (35)
- python telnet (35)
- python readlines() 方法 (36)
- munmap (35)
- docker network create (35)
- redis 集合 (37)
- python sftp (37)
- setpriority (34)
- c语言 switch (34)
- git commit (34)