感谢我的同事 李震给我讲解UDAF

网上找到的大部分都只有代码,但是缺少讲解,官网的的API有讲解,但是看不太明白。我还是自己记录一下吧,或许对其他人有帮助。

接下来以一个求几何平均数的例子来说明如何实现一个自己的UDAF

首先需要导入这些包:

import org.apache.spark.sql.expressions.MutableAggregationBuffer
import org.apache.spark.sql.expressions.UserDefinedAggregateFunction
import org.apache.spark.sql.Row
import org.apache.spark.sql.types._

需要继承实现这个抽象类
class GeometricMean extends UserDefinedAggregateFunction {
// This is the input fields for your aggregate function.
就是需要输入的列的类型,可以有多个列,多个列的写法如下:
/*
StructType(StructField("slot",IntegerType) :: StructField("score",IntegerType)::Nil)
*/
override def inputSchema: org.apache.spark.sql.types.StructType =
StructType(StructField("value", DoubleType) :: Nil) 存储聚合结果的中间buffer
// This is the internal fields you keep for computing your aggregate.
override def bufferSchema: StructType = StructType(
StructField("count", LongType) ::
StructField("product", DoubleType) :: Nil
) // This is the output type of your aggregatation function.
返回结果的类型,比如这个集合平均数就是返回一个double值
override def dataType: DataType = DoubleType

是每次运行结果都过一样,但是我也不太明白啊
override def deterministic: Boolean = true 初始化存储聚合结果的buffer
// This is the initial value for your buffer schema.
override def initialize(buffer: MutableAggregationBuffer): Unit = {
buffer(0) = 0L
buffer(1) = 1.0
}

每次更新怎么更新,比如新来了一行,如何加入更新聚合的结果
// This is how to update your buffer schema given an input.
override def update(buffer: MutableAggregationBuffer, input: Row): Unit = {
buffer(0) = buffer.getAs[Long](0) + 1
buffer(1) = buffer.getAs[Double](1) * input.getAs[Double](0)
}

spark会把数据划分成多个块,每个块都会进行处理,然后把每个块的结果进行合并处理
// This is how to merge two objects with the bufferSchema type.
override def merge(buffer1: MutableAggregationBuffer, buffer2: Row): Unit = {
buffer1(0) = buffer1.getAs[Long](0) + buffer2.getAs[Long](0)
buffer1(1) = buffer1.getAs[Double](1) * buffer2.getAs[Double](1)
}

返回结果
// This is where you output the final value, given the final value of your bufferSchema.
override def evaluate(buffer: Row): Any = {
math.pow(buffer.getDouble(1), 1.toDouble / buffer.getLong(0))
}
}

使用方法:

先注册

sqlContext.udf.register("gm", new GeometricMean)

使用自定义的UDAF
%sql
-- Use a group_by statement and call the UDAF.
select group_id, gm(id) from simple group by group_id
 
 
 

参考资料:

https://docs.databricks.com/spark/latest/spark-sql/udaf-scala.html

spark UDAF的更多相关文章

  1. Spark UDAF实现举例 -- average pooling

    目录 1.UDAF定义 2.向量平均(average pooling) 2.1 average的并行化 2.2 代码实现 2.3 使用 参考 1.UDAF定义 spark中的UDF(UserDefin ...

  2. 自定义spark UDAF

    官网链接 样例代码: import java.util.ArrayList; import java.util.List; import org.apache.spark.sql.Dataset; i ...

  3. 转:Spark User Defined Aggregate Function (UDAF) using Java

    Sometimes the aggregate functions provided by Spark are not adequate, so Spark has a provision of ac ...

  4. Spark SQL 用户自定义函数UDF、用户自定义聚合函数UDAF 教程(Java踩坑教学版)

    在Spark中,也支持Hive中的自定义函数.自定义函数大致可以分为三种: UDF(User-Defined-Function),即最基本的自定义函数,类似to_char,to_date等 UDAF( ...

  5. 【Spark篇】---SparkSql之UDF函数和UDAF函数

    一.前述 SparkSql中自定义函数包括UDF和UDAF UDF:一进一出  UDAF:多进一出 (联想Sum函数) 二.UDF函数 UDF:用户自定义函数,user defined functio ...

  6. Spark SQL UDAF示例

    UDAF:用户自定义聚合函数 Scala 2.10.7,spark 2.0.0 package UDF_UDAF import java.util import org.apache.spark.Sp ...

  7. 【Spark篇】---SparkSQL中自定义UDF和UDAF,开窗函数的应用

    一.前述 SparkSQL中的UDF相当于是1进1出,UDAF相当于是多进一出,类似于聚合函数. 开窗函数一般分组取topn时常用. 二.UDF和UDAF函数 1.UDF函数 java代码: Spar ...

  8. Spark之UDAF

    import org.apache.spark.sql.{Row, SparkSession} import org.apache.spark.sql.expressions.{MutableAggr ...

  9. Spark笔记之使用UDAF(User Defined Aggregate Function)

    一.UDAF简介 先解释一下什么是UDAF(User Defined Aggregate Function),即用户定义的聚合函数,聚合函数和普通函数的区别是什么呢,普通函数是接受一行输入产生一个输出 ...

随机推荐

  1. Centos7 下谷歌日志库GLog配置

    1 glog下载地址 https://code.google.com/archive/p/google-glog/downloads glog-0.3.3.tar.gz 需要FQ,直接打不开 2 解压 ...

  2. 10.php引用(&)详解及注意事项

    <?php function &test() { static $b=0;//申明一个静态变量 $b=$b+1; echo $b; return $b; } $a=test();//这条 ...

  3. YARN - Yet Another Resource Negotiator

    http://www.socc2013.org/home/program http://www.ibm.com/developerworks/cn/opensource/os-cn-hadoop-ya ...

  4. selectedIndex返回被选中的option的index.

    / <label for="city">城市</label> <select id="city" name="schoo ...

  5. Linux(8)- nginx+uWSGI+virtualenv+supervisor 发布web服务器

    一.理论梳理 WSGI是web服务器的网关接口,它是一个规范,描述了web服务器(下图中的WEB server)如何与web应用程序(下图中的Application)通信,以及web应用程序如何链接在 ...

  6. Python高级教程-迭代

    Python中的迭代 如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们成为迭代(Iteration). 在Python中,迭代是通过for...in ...

  7. sql server自动化运维脚本

    数据库运维中盛传一个小段子,我误删除了数据库,改怎么办?有备份还原备份,没有备份就准备简历!听起来有趣但发生在谁身上,谁都笑不起来.接触了很多的客户发现90%客户的运维策略都不是很完善.本篇就分享一些 ...

  8. 安装MySQL版本为mysql-installer-community-5.7.17.msi

    双击MySQL安装包, 勾选复选框,点击下一步: 选择仅仅服务器模式,点击下一步: 直接点击执行: 执行完成,点击下一步: 确认配置,点击下一步: 输入用户名和密码,点击下一步: 默认选项,点击下一步 ...

  9. VIM 配置python

    Pre-install sudo yum install automake gcc gcc-c++ kernel-devel cmake sudo yum install python-devel p ...

  10. Hadoop源码如何查看

    如何查看hadoop源码 1解压hadoop安装压缩文件成为文件夹,再进入解压后的文件夹下的src文件夹,选中core,hdfs,mapred三个文件夹