Java窗口函数框架JDFrame

1、简介

在上一节中已经介绍过 JDFrame,文章链接stream流太难用了看看JDFrame 没看过的朋友可以先看看,
这次主要讲讲窗口函数相关API的使用

在各种数据库mysql, hive、spark中都有非常好用的开窗函数使用, 但是java却没好用的JVM层级的窗口函数使用,于是乎写了这个,如果能熟练使用开窗函数相信能在业务代码中大大减少我们的统计计算逻辑代码。

本文不会介绍每个开窗函数是什么,它的语义与其他语言的窗口函数一模一样,在这里仅作简单介绍,后续会出相关实战的数据分析案例。

2、Maven依赖


<dependency><groupId>io.github.burukeyou</groupId><artifactId>jdframe</artifactId><version>0.0.4</version>
</dependency>

3、窗口函数的API使用

测试代码

static List<WebPvDto> dataList = new ArrayList<>();static {dataList.add(new WebPvDto("a",0,1));dataList.add(new WebPvDto("a",1,5));dataList.add(new WebPvDto("a",2,7));dataList.add(new WebPvDto("a",3,3));dataList.add(new WebPvDto("a",4,2));dataList.add(new WebPvDto("a",5,4));dataList.add(new WebPvDto("a",6,4));dataList.add(new WebPvDto("b",7,1));dataList.add(new WebPvDto("b",8,4));dataList.add(new WebPvDto("b",7,6));dataList.add(new WebPvDto("b",8,2));
}@Data
public static class WebPvDto {private String type;private Integer score;private Integer pvCount;public Object value;
}

ROW_NUMBER 窗口函数

生成行号,从1开始

// 等价于 select ROW_NUMBER() over(partition by type order pv_count desc)
SDFrame.read(dataList).window(Window.groupBy(WebPvDto::getType).sortDesc(WebPvDto::getPvCount)).overRowNumberS(WebPvDto::setValue).show(30);

输出结果:

type	score	pvCount	value	
a   	2    	7      	1    	
a   	1    	5      	2    	
a   	5    	4      	3    	
a   	6    	4      	4    	
a   	3    	3      	5    	
a   	4    	2      	6    	
a   	0    	1      	7    	
b   	7    	6      	1    	
b   	8    	4      	2    	
b   	8    	2      	3    	
b   	7    	1      	4 

RANK 窗口函数

生成排名号,相同值排名一样,排名不连续 。 如: 1 2 2 2 5 6 7

// 等价于 select rank() over(partition by type order pv_count desc)
SDFrame.read(dataList).window(Window.groupBy(WebPvDto::getType).sortDesc(WebPvDto::getPvCount)).overRankS(WebPvDto::setValue).show(30);

输出结果

type	score	pvCount	value	
a   	2    	7      	1    	
a   	1    	5      	2    	
a   	5    	4      	3    	
a   	6    	4      	3    	
a   	3    	3      	5    	
a   	4    	2      	6    	
a   	0    	1      	7    	
b   	7    	6      	1    	
b   	8    	4      	2    	
b   	8    	2      	3    	
b   	7    	1      	4    	

DENSE_RANK 窗口函数

生成排名号,相同值排名一样,排名连续 如 1 2 2 2 3 4 5

// 等价于 select  DENSE_RANK() over(partition by type order pv_count desc)
SDFrame.read(dataList).window(Window.groupBy(WebPvDto::getType).sortDesc(WebPvDto::getPvCount)).overDenseRankS(WebPvDto::setValue).show(30);

输出结果:

type	score	pvCount	value	
a   	2    	7      	1    	
a   	1    	5      	2    	
a   	5    	4      	3    	
a   	6    	4      	3    	
a   	3    	3      	4    	
a   	4    	2      	5    	
a   	0    	1      	6    	
b   	7    	6      	1    	
b   	8    	4      	2    	
b   	8    	2      	3    	
b   	7    	1      	4 

PERCENT_RANK 窗口函数

// 等价于 select  PERCENT_RANK() over(partition by type order pv_count desc)
SDFrame.read(dataList).defaultScale(6).window(Window.groupBy(WebPvDto::getType).sortDesc(WebPvDto::getPvCount)).overPercentRankS(WebPvDto::setValue).show(30);

输出结果

type	score	pvCount	value   	
a   	2    	7      	0       	
a   	1    	5      	0.166667	
a   	5    	4      	0.333333	
a   	6    	4      	0.333333	
a   	3    	3      	0.666667	
a   	4    	2      	0.833333	
a   	0    	1      	1.000000	
b   	7    	6      	0       	
b   	8    	4      	0.333333	
b   	8    	2      	0.666667	
b   	7    	1      	1.000000

Count窗口函数

//  等价于SQL:  select count(*) over(partition by type order by pv_count desc rows between UNBOUNDED PRECEDING and CURRENT ROW)
SDFrame.read(dataList).window(Window.groupBy(WebPvDto::getType).sortDesc(WebPvDto::getPvCount).roundStartRow2CurrentRow()).overCountS(WebPvDto::setValue).show(30);

输出结果:

type	score	pvCount		value	
a   	2    	7      	    	1    	
a   	1    	5      	    	2    	
a   	5    	4      	    	3    	
a   	6    	4      	    	4    	
a   	3    	3      	    	5    	
a   	4    	2      	    	6    	
a   	0    	1      	    	7    	
b   	7    	6      	    	1    	
b   	8    	4      	    	2    	
b   	8    	2      	    	3    	
b   	7    	1      	    	4    

Sum窗口函数

// 等价于 select sum(pv_count) over(rows between 1 PRECEDING and 2 FOLLOWING)
JDFrame.read(dataList).window(Window.roundBetweenBy(Range.BEFORE(1),Range.AFTER(2))).overSumS(WebPvDto::setValue,WebPvDto::getPvCount).show(30);

输出结果:

type	score	pvCount		value	
a   	0    	1      	    	13   	
a   	1    	5      	    	16   	
a   	2    	7      	    	17   	
a   	3    	3      	    	16   	
a   	4    	2      	    	13   	
a   	5    	4      	    	11   	
a   	6    	4      	    	13   	
b   	7    	1      	    	15   	
b   	8    	4      	    	13   	
b   	7    	6      	    	12   	
b   	8    	2      	    	8    

Avg窗口函数

// 等价于 select avg(pv_count) over(partition by type )
SDFrame.read(dataList).defaultScale(4).window(Window.groupBy(WebPvDto::getType)).overAvgS(WebPvDto::setValue,WebPvDto::getPvCount).show(30);

输出结果

type	score	pvCount	value 	
a   	0    	1      	3.7143	
a   	1    	5      	3.7143	
a   	2    	7      	3.7143	
a   	3    	3      	3.7143	
a   	4    	2      	3.7143	
a   	5    	4      	3.7143	
a   	6    	4      	3.7143	
b   	7    	1      	3.2500	
b   	8    	4      	3.2500	
b   	7    	6      	3.2500	
b   	8    	2      	3.2500	

Max窗口函数

// 等价于 select max(pv_count) over(partition by type order pv_count asc)
SDFrame.read(dataList).window(Window.groupBy(WebPvDto::getType).sortAsc(WebPvDto::getPvCount)).overMaxValueS(WebPvDto::setValue,WebPvDto::getPvCount).show(30);

输出结果:

type	score	pvCount	value	
a   	0    	1      	7    	
a   	4    	2      	7    	
a   	3    	3      	7    	
a   	5    	4      	7    	
a   	6    	4      	7    	
a   	1    	5      	7    	
a   	2    	7      	7    	
b   	7    	1      	6    	
b   	8    	2      	6    	
b   	8    	4      	6    	
b   	7    	6      	6  

Min窗口函数

// 等价于 select min(pv_count) over(rows between CURRENT ROW and 2 FOLLOWING)
SDFrame.read(dataList).window(Window.roundCurrentRow2AfterBy(2)).overMinValueS(WebPvDto::setValue,WebPvDto::getPvCount).show(30);
type	score	pvCount	value	
a   	0    	1      	1    	
a   	1    	5      	3    	
a   	2    	7      	2    	
a   	3    	3      	2    	
a   	4    	2      	2    	
a   	5    	4      	1    	
a   	6    	4      	1    	
b   	7    	1      	1    	
b   	8    	4      	2    	
b   	7    	6      	2    	
b   	8    	2      	2   

Lag窗口函数

获取当前行的前N行数据

// 等价于 select lag(pv_count,2) over(partition by type order pv_count desc)
SDFrame.read(dataList).window(Window.groupBy(WebPvDto::getType).sortDesc(WebPvDto::getPvCount)).overLagS(WebPvDto::setValue,WebPvDto::getPvCount,2).show(30);

输出结果:

type	score	pvCount	value	
a   	2    	7      	     	
a   	1    	5      	     	
a   	5    	4      	7    	
a   	6    	4      	5    	
a   	3    	3      	4    	
a   	4    	2      	4    	
a   	0    	1      	3    	
b   	7    	6      	     	
b   	8    	4      	     	
b   	8    	2      	6    	
b   	7    	1      	4  

Lead窗口函数

获取当前行的后N行数据

// 等价于 select lead(pv_count,3) over()
SDFrame.read(dataList).window().overLeadS(WebPvDto::setValue,WebPvDto::getPvCount,3).show(30);

输出结果:

type	score	pvCount	value	
a   	0    	1      	3    	
a   	1    	5      	2    	
a   	2    	7      	4    	
a   	3    	3      	4    	
a   	4    	2      	1    	
a   	5    	4      	4    	
a   	6    	4      	6    	
b   	7    	1      	2    	
b   	8    	4      	     	
b   	7    	6      	     	
b   	8    	2  

NthValue 窗口函数

获取窗口范围内的第N行数据

// 等价于 select NTH_VALUE(pv_count,2) over(rows between 1 PRECEDING and CURRENT ROW)
SDFrame.read(dataList).window(Window.roundBefore2CurrentRowBy(3)).overNthValueS(WebPvDto::setValue,WebPvDto::getPvCount,2).show(30);

输出结果:

type	score	pvCount	value	
a   	0    	1      	     	
a   	1    	5      	5    	
a   	2    	7      	5    	
a   	3    	3      	5    	
a   	4    	2      	7    	
a   	5    	4      	3    	
a   	6    	4      	2    	
b   	7    	1      	4    	
b   	8    	4      	4    	
b   	7    	6      	1    	
b   	8    	2      	4   

FirstValue 窗口函数

获取窗口范围内的第1行数据

// 等价于 select FIRST_VALUE(pv_count) over(rows between 2 PRECEDING and CURRENT ROW)
SDFrame.read(dataList).window(Window.roundBetweenBy(Range.BEFORE(2), Range.CURRENT_ROW)).overFirstValueS(WebPvDto::setValue,WebPvDto::getPvCount).show(30);
type	score	pvCount	value	
a   	0    	1      	1    	
a   	1    	5      	1    	
a   	2    	7      	1    	
a   	3    	3      	5    	
a   	4    	2      	7    	
a   	5    	4      	3    	
a   	6    	4      	2    	
b   	7    	1      	4    	
b   	8    	4      	4    	
b   	7    	6      	1    	
b   	8    	2      	4 

LastValue 窗口函数

获取窗口范围内的最后一行数据

// 等价于 select LAST_VALUE(pv_count) over(rows between 2 PRECEDING and 2 FOLLOWING)
SDFrame.read(dataList).window(Window.roundBeforeAfterBy(2,2)).overLastValueS(WebPvDto::setValue,WebPvDto::getPvCount).show(30);

输出结果

type	score	pvCount	value	
a   	0    	1      	7    	
a   	1    	5      	3    	
a   	2    	7      	2    	
a   	3    	3      	4    	
a   	4    	2      	4    	
a   	5    	4      	1    	
a   	6    	4      	4    	
b   	7    	1      	6    	
b   	8    	4      	2    	
b   	7    	6      	     	
b   	8    	2   

Ntile 窗口函数

给窗口尽量均匀的分成N个桶, 每个桶的编号从1开始, 如果分布不均匀,则优先分配给最小的桶,桶之间的大小差值最多不超过1

// 等价于 select  Ntile(3) over(partition by type order pv_count desc)
SDFrame.read(dataList).window(Window.groupBy(WebPvDto::getType)).overNtileS(WebPvDto::setValue,3).show(30);

输出结果:

type	score	pvCount	value	
a   	0    	1      	1    	
a   	1    	5      	1    	
a   	2    	7      	1    	
a   	3    	3      	1    	
a   	4    	2      	2    	
a   	5    	4      	2    	
a   	6    	4      	2    	
b   	7    	1      	2    	
b   	8    	4      	3    	
b   	7    	6      	3    	
b   	8    	2      	3 

Cume_Dist 窗口函数

累积分布值, 统计的是 (小于等于当前排名号的行数 / 窗口行数) 的比率

// select  cume_dist() over(partition by type order pv_count desc)
SDFrame.read(dataList).window(Window.groupBy(WebPvDto::getType).sortDesc(WebPvDto::getPvCount)).overCumeDistS(WebPvDto::setValue).show(30);

输出结果

type	score	pvCount	value	
a   	2    	7      	0.14 	
a   	1    	5      	0.29 	
a   	5    	4      	0.57 	
a   	6    	4      	0.57 	
a   	3    	3      	0.71 	
a   	4    	2      	0.86 	
a   	0    	1      	1.00 	
b   	7    	6      	0.25 	
b   	8    	4      	0.50 	
b   	8    	2      	0.75 	
b   	7    	1      	1.00 

4 窗口

主要是通过Window对象去构建开窗的信息,包括窗口的分区情况,窗口的排序情况,还有窗口范围。
窗口范围可以通过 Range对象去枚举指定。

如果不指定窗口信息默认窗口范围就是全部行。 众所周知而在 mysql中如果使用了order默认窗口范围就是 rows between UNBOUNDED PRECEDING and CURRENT ROW, 如果没有使用order也没指定rows between, 默认窗口范围才是全部。 这点要注意区分

5 最后

1、窗口函数的计算结果的存储有两种方式,一种是直接返回到FI2里, 一种是可以通过指定SetFunction 进行存储, 所有后缀带S的方法就是通过后者的方式的存储, 之所以带S后缀是为了以便于区分,并且是放到第一个方法参数里。

2、除了可以通过单独的window()的方法去指定窗口信息,在每个over方法也可以了单独设置。 没单独设置就使用window()方法里指定的窗口信息

3、在不同窗口范围内的数据计算目前用的是各种滑动窗口算法,时间复杂度基本在O(N)左右

代码地址

Maven依赖地址

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

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

相关文章

数据结构与算法学习笔记十---链队列的表示和实现(C语言)

目录 前言 1.什么是链队 2.链队的表示和实现 1.定义 2.初始化 3.销毁 4.清空 5.空队列 6.队列长度 7.获取队头 8.入队 9.出队 10.遍历队列 11.完整代码 前言 本篇博客介绍链栈队列的表示和实现。 1.什么是链队 链队是采用链式存储结构实现的队列。通常链队使用单…

【知识拓展】大白话说清楚:IP地址、子网掩码、网关、DNS等

前言 工作中常听别人说的本地网络是什么意思&#xff1f;同一网段又是什么意思&#xff1f;它俩有关系吗&#xff1f; 在工作中内经常会遇到相关的网络问题&#xff0c;涉及网络通信中一些常见的词汇&#xff0c;如IP地址、子网掩码、网关和DNS等。具体一点&#xff1a;经常会…

申请免费的必应搜索API

申请免费的必应搜索API 文章目录 申请免费的必应搜索API前言一、原理1.1 登录1.2 进入1.3 获取密钥1.4 申请VISA信用卡1.5 创建必应自定义搜索资源 二、创建成功 前言 准备条件&#xff1a; 1、outlook邮箱 2、招商银行全币种VISA信用卡【建议之前就有一张招商银行信用卡&…

【opencv】图像拼接实验

实验环境&#xff1a;anaconda、jupyter notebook 实验用到的包&#xff1a;opencv、matplotlib、numpy 注&#xff1a;opencv在3.4.2之后sift就不是免费的了 我用的是3.4.1.15版本 实验使用到的图片 一、sift函数获取特征值 读入图片 book cv2.imread(book.png, cv2.IMRE…

【极简】如何估算大模型inference所需的内存量

1字节8bit 16float2字节 模型后面的xxb的单位是字节。 1b 字节≈ 0.93G&#xff0c;这个是以8bit运行&#xff0c;4bit减半&#xff0c;16bit&#xff08;float&#xff09;加倍&#xff0c;32bit&#xff08;double&#xff09;炒鸡加倍。 剩下的是小头&#xff0c;需要参数计…

苹果macOS无法给App麦克风授权解决办法

好久没有在电脑上录制课程了&#xff0c;有些东西还是录下来记忆深刻&#xff0c;却意外发现MAC系统升级后无法授权给第三方的App使用摄像头和麦克风&#xff0c;而录屏软件是需要开启麦克风和摄像头才能录制屏幕上的操作和声音&#xff0c;官方提示在第三方APP若有使用摄像头和…

css的4种导入方式

熟悉CSS样式4种的引用方式&#xff0c;分别为行内式、内嵌式、链入式和导入式。 行内式 <标签名 style"属性1:属性值1;属性2:属性值2;属性3:属性值3;">内容</ 标签名>style是标签的属性&#xff0c;实际上任何HTML标签都拥有style属性&#xff0c;用来…

pyqt QComboBox下拉列表框控件

pyqt QComboBox下拉列表框控件 QComboBox效果代码 QComboBox QComboBox 是 PyQt&#xff08;中的一个控件&#xff0c;它允许用户从下拉列表中选择一个选项。这个控件在需要用户从预定义选项中进行选择时非常有用。 效果 代码 import sys from PyQt5.QtWidgets import QAppl…

vite创建的项目使用rem适配

下面以创建vue3.0 项目为例&#xff1a; npm init vitelatest “名称” 选择vue &#xff08;选择你所对应的语言&#xff09; 更具提示步骤执行 cd xxx npm i npm run dev 然后再项目中使用 rem 需要安装插件 第一步安装插件 npm i amfe-flexible npm i postcss-pxtorem 第二…

CS144 Checkpoint 4: interoperating in the world(2024)

分析网络路径和性能&#xff1a; mtr命令 mtr 输出的详细分析&#xff1a; mtr 162.105.253.58 命令用于结合 traceroute 和 ping 的功能&#xff0c;实时监测并分析从你的计算机到目标主机&#xff08;IP 地址 162.105.253.58&#xff0c;北京大学计算中心&#xff09;之间…

Nginx配置Referer防盗链

系列文章目录 文章目录 系列文章目录前言 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff0c;这篇文章男女通用&#xff0c;看懂了就去分享给你的码吧。 HTTP Referer是Hea…

PBOOTCMS|URL静态制作教程(已解答)

0、先解压源码文件&#xff0c;在覆盖静态文件&#xff0c;全部点是。 打开程序后台登录地址www.xxx.com(你的域名)/admin.php/Menu/index 打开程序后台--系统菜单--菜单新增&#xff08;清理缓存后重新登录账号&#xff09; &#xff08;选择父菜单&#xff0c;菜单名称&#…

ROS2+TurtleBot3+Cartographer+Nav2实现slam建图和导航

0 引言 入门机器人最常见的应用就是slam建图和导航&#xff0c;本文将详细介绍这一流程&#xff0c; 便于初学这快速上手。 首先对需要用到的软件包就行简单介绍。 turtlebot3: 是一个小型的&#xff0c;基于ros的移动机器人。 学习机器人的很多示例程序都是基于turtlebot3。 …

【Java基础】枚举类的方法及应用

如何实现让一个类有固定个数的对象 手动封装构造方法&#xff08;private&#xff09; → 创建静态对象 → final修饰静态对象&#xff0c;使其成为常量 class Season { //枚举类public final static Season SPRING new Season();public final static Season SUMMER new Se…

MySQL数据库备份全攻略:从基础到高级,一文掌握所有备份技巧

在数据为王的时代&#xff0c;数据库的备份无疑是每一位数据库管理员&#xff08;DBA&#xff09;和开发者必须掌握的核心技能。MySQL作为世界上最流行的开源关系型数据库管理系统&#xff0c;其备份策略的多样性和灵活性更是值得我们深入探讨。今天&#xff0c;我们将从基础的…

废品回收微信小程序基于FastAdmin+ThinkPHP+UniApp(源码搭建/上线/运营/售后/更新)

一款基于FastAdminThinkPHPUniApp开发的废品回收系统&#xff0c;适用废品回收站、再生资源回收公司上门回收使用的小程序。 一、FastAdmin框架特色功能及优势 模块化开发&#xff1a;控制器、模型、视图、JS一一对应&#xff0c;使用RequireJS进行插件机制&#xff0c;支持插…

Java面试题:线程池的核心参数和工作原理

线程池的核心参数 ThreadPoolExecutor(int corePoolSize,//核心线程数目int MaximumPoolSize,//最大线程数核心线程临时线程long keepAliveTime,//临时线程的存活时间,在存活时间内如果没有新任务,线程资源会被释放TimeUnit unit,//存活时间的时间单位,一个枚举类型BlockingQu…

sql操作、发送http请求和邮件发送 全栈开发之路——后端篇(2)

全栈开发一条龙——前端篇 第一篇&#xff1a;框架确定、ide设置与项目创建 第二篇&#xff1a;介绍项目文件意义、组件结构与导入以及setup的引入。 第三篇&#xff1a;setup语法&#xff0c;设置响应式数据。 第四篇&#xff1a;数据绑定、计算属性和watch监视 第五篇 : 组件…

STL介绍及使用场景分析

一.总体介绍 STL&#xff08;Standard Template Library&#xff09;是C标准模板库&#xff0c;提供了一系列的通用模板类和函数&#xff0c;用于实现常见的数据结构和算法&#xff0c;方便开发者快速地实现各种功能。STL包括了容器&#xff08;Containers&#xff09;、算法&a…

[BJDCTF 2020]easy_md5、[HNCTF 2022 Week1]Interesting_include、[GDOUCTF 2023]泄露的伪装

目录 [BJDCTF 2020]easy_md5 ffifdyop [SWPUCTF 2021 新生赛]crypto8 [HNCTF 2022 Week1]Interesting_include php://filter协议 [GDOUCTF 2023]泄露的伪装 [BJDCTF 2020]easy_md5 尝试输入一个1&#xff0c;发现输入的内容会通过get传递但是没有其他回显 观察一下响应…