在window10下安装了hadoop,用ida创建maven项目。

    <properties>
<spark.version>2.2.0</spark.version>
<scala.version>2.11</scala.version>
<java.version>1.8</java.version>
</properties> <dependencies>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_${scala.version}</artifactId>
<version>${spark.version}</version>
</dependency>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-sql_${scala.version}</artifactId>
<version>${spark.version}</version>
</dependency>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-streaming_${scala.version}</artifactId>
<version>${spark.version}</version>
</dependency>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-yarn_${scala.version}</artifactId>
<version>${spark.version}</version>
</dependency> <dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
</dependencies> <build>
<finalName>learnspark</finalName>
<plugins>
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<version>3.2.2</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<archive>
<manifest>
<mainClass>learn</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

  

数据准备:

{"name":"张3", "age":20}
{"name":"李4", "age":20}
{"name":"王5", "age":20}
{"name":"赵6", "age":20}
路径:
data/input/user/user.json
程序:
package com.zouxxyy.spark.sql

import org.apache.spark.SparkConf
import org.apache.spark.sql.expressions.{Aggregator, MutableAggregationBuffer, UserDefinedAggregateFunction}
import org.apache.spark.sql.types.{DataType, DoubleType, LongType, StructType}
import org.apache.spark.sql.{Column, DataFrame, Dataset, Encoder, Encoders, Row, SparkSession, TypedColumn} /**
* UDF:用户自定义函数
*/ object UDF { def main(args: Array[String]): Unit = {
System.setProperty("hadoop.home.dir","D:\\gitworkplace\\winutils\\hadoop-2.7.1" )
//这个是用来指定我的hadoop路径的,如果你的hadoop环境变量没问题,可以不写
val sparkConf: SparkConf = new SparkConf().setMaster("local[*]").setAppName("UDF") // 创建SparkSession
val spark: SparkSession = SparkSession.builder.config(sparkConf).getOrCreate() import spark.implicits._ // 从json中read得到的是DataFrame
val frame: DataFrame = spark.read.json("data/input/user/user.json") frame.createOrReplaceTempView("user") // 案例一:自定义一个简单的函数测试
spark.udf.register("addName", (x:String)=> "Name:"+x) spark.sql("select addName(name) from user").show() // 案例二:自定义一个弱类型聚合函数测试 val udaf1 = new MyAgeAvgFunction spark.udf.register("avgAge", udaf1) spark.sql("select avgAge(age) from user").show() // 案例三:自定义一个强类型聚合函数测试 val udaf2 = new MyAgeAvgClassFunction // 将聚合函数转换为查询列
val avgCol: TypedColumn[UserBean, Double] = udaf2.toColumn.name("aveAge") // 用强类型的Dataset的DSL风格的编程语法
val userDS: Dataset[UserBean] = frame.as[UserBean] userDS.select(avgCol).show() spark.stop()
}
} /**
* 自定义内聚函数(弱类型)
*/ class MyAgeAvgFunction extends UserDefinedAggregateFunction{ // 输入的数据结构
override def inputSchema: StructType = {
new StructType().add("age", LongType)
} // 计算时的数据结构
override def bufferSchema: StructType = {
new StructType().add("sum", LongType).add("count", LongType)
} // 函数返回的数据类型
override def dataType: DataType = DoubleType // 函数是否稳定
override def deterministic: Boolean = true // 计算前缓存区的初始化
override def initialize(buffer: MutableAggregationBuffer): Unit = {
// 没有名称,只有结构
buffer(0) = 0L
buffer(1) = 0L
} // 根据查询结果,更新缓存区的数据
override def update(buffer: MutableAggregationBuffer, input: Row): Unit = {
buffer(0) = buffer.getLong(0) + input.getLong(0)
buffer(1) = buffer.getLong(1) + 1
} // 多个节点的缓存区的合并
override def merge(buffer1: MutableAggregationBuffer, buffer2: Row): Unit = {
buffer1(0) = buffer1.getLong(0) + buffer2.getLong(0)
buffer1(1) = buffer1.getLong(1) + buffer2.getLong(1)
} // 计算缓存区里的东西,得最终返回结果
override def evaluate(buffer: Row): Any = {
buffer.getLong(0).toDouble / buffer.getLong(1)
}
} /**
* 自定义内聚函数(强类型)
*/ case class UserBean (name : String, age : BigInt) // 文件读取数字默认是BigInt
case class AvgBuffer(var sum: BigInt, var count: Int) class MyAgeAvgClassFunction extends Aggregator[UserBean, AvgBuffer, Double] { // 初始化缓存区
override def zero: AvgBuffer = {
AvgBuffer(0, 0)
} // 输入数据和缓存区计算
override def reduce(b: AvgBuffer, a: UserBean): AvgBuffer = {
b.sum = b.sum + a.age
b.count = b.count + 1
// 返回b
b
} // 缓存区的合并
override def merge(b1: AvgBuffer, b2: AvgBuffer): AvgBuffer = {
b1.sum = b1.sum + b2.sum
b1.count = b1.count + b2.count b1
} // 计算返回值
override def finish(reduction: AvgBuffer): Double = {
reduction.sum.toDouble / reduction.count
} override def bufferEncoder: Encoder[AvgBuffer] = Encoders.product override def outputEncoder: Encoder[Double] = Encoders.scalaDouble
}

  

scala的应用--UDF:用户自定义函数的更多相关文章

  1. 15第十五章UDF用户自定义函数(转载)

    15第十五章UDF用户自定义函数 待补上 原文链接 本文由豆约翰博客备份专家远程一键发布

  2. Hive UDF 用户自定义函数 编程及使用

    首先创建工程编写UDF 代码,示例如下: 1. 新建Maven项目 udf 本机Hadoop版本为2.7.7, Hive版本为1.2.2,所以选择对应版本的jar ,其它版本也不影响编译. 2. po ...

  3. SQL Server UDF用户自定义函数

    UDF的定义 和存储过程很相似,用户自定义函数也是一组有序的T-SQL语句,UDF被预先优化和编译并且尅作为一个单元爱进行调用.UDF和存储过程的主要区别在于返回结果的方式. 使用UDF时可传入参数, ...

  4. Hive的UDF(用户自定义函数)开发

    当 Hive 提供的内置函数无法满足你的业务处理需要时,此时就可以考虑使用用户自定义函数(UDF:user-defined function). 测试各种内置函数的快捷方法: 创建一个 dual 表 ...

  5. Pig UDF 用户自定义函数

    注册UDF do.pig的内容如下: register /xx/yy.jar data = load 'data'; result = foreach data generate aa.bb.Uppe ...

  6. Hive中的用户自定义函数UDF

    Hive中的自定义函数允许用户扩展HiveQL,是一个非常强大的功能.Hive中具有多种类型的用户自定义函数.show functions命令可以列举出当前Hive会话中的所加载进来的函数,包括内置的 ...

  7. 详解Spark sql用户自定义函数:UDF与UDAF

    UDAF = USER DEFINED AGGREGATION FUNCTION Spark sql提供了丰富的内置函数供猿友们使用,辣为何还要用户自定义函数呢?实际的业务场景可能很复杂,内置函数ho ...

  8. SQL Server用户自定义函数(UDF)

    一.UDF的定义 和存储过程很相似,用户自定义函数也是一组有序的T-SQL语句,UDF被预先优化和编译并且可以作为一个单元来进行调用. UDF和存储过程的主要区别在于返回结果的方式: 使用UDF时可传 ...

  9. Hive 文件格式 & Hive操作(外部表、内部表、区、桶、视图、索引、join用法、内置操作符与函数、复合类型、用户自定义函数UDF、查询优化和权限控制)

    本博文的主要内容如下: Hive文件存储格式 Hive 操作之表操作:创建外.内部表 Hive操作之表操作:表查询 Hive操作之表操作:数据加载 Hive操作之表操作:插入单表.插入多表 Hive语 ...

随机推荐

  1. HeadFirst设计模式---装饰者

    定义装饰者模式 装饰者模式动态地将责任附加到对象上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案.这句话摘自书中,给人读得很生硬难懂.通俗地来说,装饰者和被装饰者有相同的父类,装饰者的行为组装着 ...

  2. 8.如何自己设计一个类似 Dubbo 的 RPC 框架?

    作者:中华石杉 面试题 如何自己设计一个类似 Dubbo 的 RPC 框架? 面试官心理分析 说实话,就这问题,其实就跟问你如何自己设计一个 MQ 一样的道理,就考两个: 你有没有对某个 rpc 框架 ...

  3. Transformer —— attention is all you need

    https://www.cnblogs.com/rucwxb/p/10277217.html Transformer -- attention is all you need Transformer模 ...

  4. Python语言基础07-面向对象编程基础

    本文收录在Python从入门到精通系列文章系列 1. 了解面对对象编程 活在当下的程序员应该都听过"面向对象编程"一词,也经常有人问能不能用一句话解释下什么是"面向对象编 ...

  5. C++编译错误 --- 成员函数定义在 .h 文件中出现重定义错误(Error LNK 2005)

    今天写了一个简单的类,定义在 .h 文件中, 类很简单就将其成员函数定义在了一起(class类后面).运行的时候出现了如下图所示的编译错误(error LNK2005) 查资料,大部分都是说需要加上 ...

  6. 使用Nginx+Openresty实现WAF功能

    什么是WAF Web应用防护系统(也称为:网站应用级入侵防御系统.英文:Web Application Firewall,简称: WAF).利用国际上公认的一种说法:Web应用防火墙是通过执行一系列针 ...

  7. JS高阶---闭包(循环遍历+监听)

    大纲: 主体: (1)场景1:点击按钮显示点击的第几个 注意:伪数组每次循环时都会重新计算一次长度,所以最好提出去或者直接加到for循环内部 结果: 分析: 1.i为全局变量 解决方案: 1.下标法 ...

  8. 集合(List、Set、Map)

    一.集合与数组 数组:长度固定,数组元素可以是基本类型,也可以是对象.不适合在对象数量未知的情况下使用. 集合:(只能存储对象,对象类型可以不一样)的长度可变,可在多数情况下使用. Java集合类存放 ...

  9. leetcode206. 反转链表

    1:迭代法 假设存在链表 1 → 2 → 3 → Ø,我们想要把它改成 Ø ← 1 ← 2 ← 3. 在遍历列表时,将当前节点的 next 指针改为指向前一个元素.由于节点没有引用其上一个节点,因此必 ...

  10. leetcode14最长公共前缀

    class Solution { public: string longestCommonPrefix(vector<string>& strs) { ) return " ...