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.pswp.cn/diannao/12357.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/12357.shtml
英文地址,請注明出處:http://en.pswp.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傳遞但是沒有其他回顯 觀察一下響應…