自定义函数

Spark自定义函数

spark 中的 UDF (UserDefinedFunction) 大家都不会陌生, UDF 其实就是将一个普通的函数, 包装为可以按 “行“ 操作的函数, 用来处理 DataFrame 中指定的 Columns.
例如, 对某一列的所有元素进行 +1 操作, 它对应 mapreduce 操作中的 map 操作. 这种操作有的主要特点是: 行与行之间的操作是 独立 的, 可以非常方便的 并行计算 每一行的操作完成后, map 的任务就完成了, 直接将结果返回就行, 它是一种”无状态的“
但是 UDAF (UserDefinedAggregateFunction) 则不同, 由于存在聚合 (Aggregate) 操作, 它对应 mapreduce 操作中的 reduce 操作. SparkSQL中有很多现成的聚合函数, 常用的 sum, count, avg 等等都是.
这种操作的主要特点是: 每一轮 reduce 之间可以是并行, 但是多轮 reduce 的执行是 串行 的, 下一轮依靠前一轮的结果, 它是一种“有状态的”, 需要记录中间的计算结果

import org.apache.commons.lang3.StringUtils
import org.apache.spark.sql.{SparkSession, functions}
import org.apache.spark.sql.expressions.UserDefinedFunctionimport java.utilobject udf_manage {val spark: SparkSession = SparkUtils.getBuilder.getOrCreate()/*** dt yyyy-MM-dd*/val getQuarterMapFunction: UserDefinedFunction = spark.udf.register("getQuarterFunction",(dt: String) => {StringUtil.assertNotBlank(dt, "dt is empty!!!")val month = dt.split("-")(1)month match {case "01" | "02" | "03" => "1"case "04" | "05" | "06" => "2"case "07" | "08" | "09" => "3"case "10" | "11" | "12" => "4"case _ => throw new RuntimeException(s"不支持的日期:$dt")}})/*** yyyy-MM-dd HH:mm:ss*/val getDtMapFunction: UserDefinedFunction = spark.udf.register("getDtMapFunction", (acquisitionTime: String) => {val dt = acquisitionTime.split(" ")(0)dt})val getDhMapFunction: UserDefinedFunction = spark.udf.register("getDhMapFunction", (acquisitionTime: String) => {val dh = acquisitionTime.split(" ")(1).split(":")(0)dh})val getDmMapFunction: UserDefinedFunction = spark.udf.register("getDmMapFunction", (acquisitionTime: String) => {val dm = acquisitionTime.split(" ")(1).split(":")(1).toIntif (dm >= 0 && dm < 15) {"00"} else if (dm >= 15 && dm < 30) {"15"} else if (dm >= 30 && dm < 45) {"30"} else {"45"}})val nullMapFunction: UserDefinedFunction = spark.udf.register("nullMapFunction",(str: String) => {val r = str match {case null | "" => "NULL"case _ => str}r})val natureMapFunction: UserDefinedFunction = spark.udf.register("natureMapFunction",(project_nature: String) => {val r = project_nature match {case "366" | "368" | "385" | "386" => project_naturecase _ => "378"}r})val monthMapFunction: UserDefinedFunction = spark.udf.register("monthMapFunction", (cost_month: String, default: String) => {//202305if (StringUtils.isNotBlank(cost_month) && cost_month.length == 6) {val year = cost_month.substring(0, 4)val month = cost_month.substring(4)s"$year-$month-01"} else {default}})/*** a,b,c,c,d* 这类以,进行拼接的string的去重计数*/val idsCntsUDF: UserDefinedFunction = spark.udf.register("idsCntsUDF",(ids: String) => {val set = new util.HashSet[String]()if (null != ids) {ids.split(",").foreach(e => {if (StringUtils.isNotBlank(e)) {set.add(e)}})}set.size()})val avgScoreUDF: UserDefinedFunction = spark.udf.register("avgScore",(language: Double, math: Double, english: Double) => {((language + math + english) / 3.0).formatted("%.2f").toDouble})/*** x-y-z,经过指定的分隔符分隔后的第一项替换为指定的char*/val replaceFirst: UserDefinedFunction = functions.udf[String, String, String, String]((str: String, split: String, expect: String) => {val first = str.split(split)(0)str.replace(first, expect)})
}

Spark使用UDF基于某些列的计算
该方案使用udf用于对DataFrame的某些列进行组合计算映射出一个新的列,这种方案也就简化了map操作

val monthMapFunction: UserDefinedFunction = spark.udf.register("monthMapFunction", (cost_month: String,default:String) => {//202305if (StringUtils.isNotBlank(cost_month)) {val year = cost_month.substring(0, 4)val month = cost_month.substring(4)s"$year-$month-01"} else {default}})
//加载注册的函数
udf_manage.monthMapFunction
val f2 = f1.withColumn("dMonth2", org.apache.spark.sql.functions.callUDF("monthMapFunction", lit("202305"), 
lit("1970-01-01")))

UDF使用原则

//加一列,对参数dt的处理逻辑简单,自己处理
.withColumn("year", lit(dt.split(" ")(0).split("-")(0)))
//加一列,对参数dt的处理逻辑麻烦,把参数交给udf并封装过程
.withColumn("quarter", udf_manage.getQuarterMapFunction(lit(dt)))

UDF和Map函数的使用原则
当有多个列需要处理,并且处理的逻辑并不简单,则用map配合样例类,一次性处理

Hive自定义函数


import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.hive.ql.exec.UDF;import java.util.Arrays;
import java.util.HashSet;public class StringDistinct extends UDF {public static void main(String[] args) {System.out.println(new StringDistinct().evaluate("a,b,a,b,c,b,c"));}/*** @param s=a,b,a,b,c,b,c* @return a, b, c*/public String evaluate(final String s) {if (StringUtils.isEmpty(s)) {return "";}String s1 = new HashSet<>(Arrays.asList(s.split(","))).toString();return s1.substring(1, s1.length() - 1).replace(", ", ",");}}

在hive2的节点加载jar包
add jar /mnt/db_file/jars/udf-1.0-SNAPSHOT.jar;

create temporary function idsCnts as “com.mingzhi.StringDistinctCnts”;

SELECT * from dwd_order_info_abi WHERE dt BETWEEN ‘2023-07-01’ AND ‘2023-07-31’ AND institutionid=‘481’ AND idsCnts(send_user_ids)>1;

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

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

相关文章

《opencv实用探索·一》QT+opencv实现图片拼接和Mat转QImage

本文利用opencv实现了几个好用的功能&#xff0c;包含两个文件&#xff0c;如下&#xff1a; 源码放在文章末尾 imageProcessing类包含三个功能&#xff1a; 1、图像拼接 cv::Mat imageMosaic(cv::Mat mat1, cv::Mat mat2, MosaicMode mosaicMode);mat1和mat2为两个待拼接的…

Matplotlib实现Label及Title都在下方的最佳姿势

Matplotlib实现Label及Title都在下方的最佳姿势 1. 问题背景2. 基本思想&#xff08;可以不看&#xff09;3. 方法封装4. 调用实例5. 总结6. 起飞 1. 问题背景 用python绘制下面这种图的时候&#xff0c;一般用xlable作为子图的标题&#xff0c;这是因为plt.title()方法绘制的…

人工智能:科技魔法赋予生活新意

&#x1f648;作者简介&#xff1a;练习时长两年半的Java up主 &#x1f649;个人主页&#xff1a;程序员老茶 &#x1f64a; ps:点赞&#x1f44d;是免费的&#xff0c;却可以让写博客的作者开心好久好久&#x1f60e; &#x1f4da;系列专栏&#xff1a;Java全栈&#xff0c;…

自学ansible笔记

一、认识ansible Ansible是一款开源自动化运维工具。它有如下特点&#xff1a; 1、不需要安装客户端&#xff0c;通过sshd去通信&#xff0c;比较轻量化&#xff1b; 2、基于模块工作&#xff0c;模块可以由任何语言开发&#xff0c;比较自由和开放&#xff1b; 3、不仅支持命…

WPF显示3D图形

C# 中的 WPF (Windows Presentation Foundation) 支持显示3D图形。WPF 使用 DirectX 作为底层图形引擎&#xff0c;这意味着它可以处理包括3D图形在内的复杂渲染任务。 在 WPF 中&#xff0c;你可以使用一些内置的类和控件来创建和显示3D对象。这包括 Viewport3D, Camera, Mod…

Android studio run 手机或者模拟器安装失败,但是生成了debug.apk

错误信息如下&#xff1a;Error Installation did not succeed. The application could not be installed&#xff1a;List of apks 出现中文乱码&#xff1b; 我首先尝试了打包&#xff0c;能正常安装&#xff0c;再次尝试了debug的安装包&#xff0c;也正常安装&#xff1…

再谈谷歌GMS认证之Android 13

写在前面的话 2023年来到一个新的公司&#xff0c;传说中的做互联网金融即将上市的高大上公司。 入职后才发现就是做pos机设备的一个小厂 哎&#xff0c;什么命啊&#xff01; 工作和手机开发的工作重合度可以达到95%以上&#xff0c;我不想做手机&#xff0c;偏偏又干上…

计算机基础知识54

ORM的介绍 # ORM是什么&#xff1f; 我们在使用Django框架开发web应用的过程中&#xff0c;不可避免地会涉及到数据的管理操作&#xff08;增、删、改、查&#xff09;&#xff0c;而一旦谈到数据的管理操作&#xff0c;就需要用到数据库管理软件&#xff0c;例如mysql、oracle…

Ubuntu20.0中安装Gradle

下载Gradle到temp文件夹 wget https://services.gradle.org/distributions/gradle-8.3-bin.zip -P /tmp 然后解压文件到/opt/gradle目录 sudo unzip -d /opt/gradle /tmp/gradle-8.3.zip 配置Gradle环境变量 接下来我们会创建一个gradle.sh文件来保存Gradle的环境变量 sudo…

ubuntu20.04蓝牙连接airpods

ubuntu20.04蓝牙连接airpods 解禁蓝牙安装blueman设置模式连接上没有声音的问题 解禁蓝牙 sudo rmmod btusb sleep 1 sudo modprobe btusb sudo /etc/init.d/bluetooth restart安装blueman sudo apt install blueman sudo apt-get install pulseaudio-module-bluetooth sudo …

『亚马逊云科技产品测评』活动征文|构建生态农场家禽系统

『亚马逊云科技产品测评』活动征文&#xff5c;构建生态农场家禽系统 授权声明&#xff1a;本篇文章授权活动官方亚马逊云科技文章转发、改写权&#xff0c;包括不限于在 Developer Centre, 知乎&#xff0c;自媒体平台&#xff0c;第三方开发者媒体等亚马逊云科技官方渠道 前…

VBA如何快速识别Excel单元格中的文本数字

Excel中一种非常特殊的数字&#xff0c;这些数字看似数字&#xff0c;其实是文本格式&#xff08;下文简称为文本数字&#xff09;&#xff0c;在单元格的左上角会有一个绿色小三角作为标志&#xff0c;如B1:B3单元格。 在编程时为什么需要区分普通数字和文本数字呢&#xff…

SVG圆形 <circle>的示例代码

本专栏是汇集了一些HTML常常被遗忘的知识&#xff0c;这里算是温故而知新&#xff0c;往往这些零碎的知识点&#xff0c;在你开发中能起到炸惊效果。我们每个人都没有过目不忘&#xff0c;过久不忘的本事&#xff0c;就让这一点点知识慢慢渗透你的脑海。 本专栏的风格是力求简洁…

.NET 8.0 AOT 教程 和使用 和 .NET ORM 操作

NET AOT编译是一种.NET运行时的编译方式&#xff0c;它与传统的JIT编译方式不同。在传统的JIT编译中&#xff0c;.NET应用程序的代码在运行时才会被编译成本地机器码&#xff0c;而在AOT编译中&#xff0c;代码在运行之前就被提前编译成本地机器码。这样可以在代码运行的时候不…

键盘映射笔记

dumpkeys命令用于显示当前系统中定义的键盘映射表。它可以帮助用户查看和理解系统中的键盘布局和键盘映射规则。 当用户执行dumpkeys命令时&#xff0c;它会读取系统中的键盘映射表文件&#xff08;通常是/etc/keymaps或/etc/console/boottime.kmap.gz&#xff09;&#xff0c;…

Rust unix domain socket

先用起来再说 use std::io::prelude::*; use std::os::unix::net::UnixStream;fn main() {let mut stream: UnixStream;let mut buffer vec![0u8; 4096];match UnixStream::connect("/tmp/hello.world.serv") {Ok(handle) > {stream handle;match stream.write_…

【C#二开业务冠邑】通过界面查看数据来源

前言 重构框架&#xff08;CS【C#】转BS【Java】&#xff09;时&#xff0c;突然发现公司的代码和数据库&#xff0c;有部分都没有写注释&#xff0c;嘎嘎&#xff0c;这不非常影响开发效率&#xff0c;于是乎&#xff0c;开始帮公司整理表结构和数据来源&#xff0c;也从而加…

3D全景视角,足不出户感知真实场景的魅力

近年来&#xff0c;随着科技的快速发展&#xff0c;普通的平面静态视角已经无法满足我们了&#xff0c;不管是视角框架的限制还是片面的环境展示&#xff0c;都不足以让我们深入了解场景环境。随着VR全景技术的日益成熟&#xff0c;3D全景技术的出现为我们提供了全新的视觉体验…

【C++深度剖析学习总结】28 函数对象分析

1.客户需求 编写一个函数,满足三个需求 函数可以获得斐波那契数列每项的值 每调用一次返回一个值 函数可根据需要重复使用 for(int i =0; i<10; i++) { cout << fib() << endl; } 第一个解决方案 #include<iostream> #include<string> using na…

汽车标定技术--A2L格式分析

目录 1.A2L由来 2.A2L格式 2.1 PROJECT 2.2 MODULE中包含的内容 3. INCA和CANape兼容吗&#xff1f; 最近有朋友用Vector ASAP2Editor编译的A2L文件在INCA7.4中无法识别&#xff0c;我记得以前做的时候是可以识别的&#xff0c;难不成最近有什么变动吗&#xff1f;出于好…