UDAF(用户自定义聚合函数)求众数
自定义UDAF,需要extends org.apache.spark.sql.expressions.UserDefinedAggregateFunction,并实现接口中的8个方法。
udaf写起来比较麻烦,我下面列一个之前写的取众数聚合函数,在我们通常在聚合统计的时候可能会受某条脏数据的影响。
举个栗子:
对于一个app日志聚合的时候,有id与ip,原则上一个id有一个ip,但是在多条数据里有一条ip是错误的或者为空的,这时候group能会聚合成两条数据了就,如果使用max,min对ip也进行聚合,那也不太合理,这时候可以进行投票,去类似多数对结果,从而聚合后只有一个设备。
废话少说,上代码:
import org.apache.spark.sql.Row
import org.apache.spark.sql.expressions.{MutableAggregationBuffer, UserDefinedAggregateFunction}
import org.apache.spark.sql.types._ /**
* Description: 自定义聚合函数:众数(取列内频率最高的一条)
*/ class UDAFGetMode extends UserDefinedAggregateFunction {
override def inputSchema: StructType = {
StructType(StructField("inputStr", StringType, true) :: Nil)
} override def bufferSchema: StructType = {
StructType(StructField("bufferMap", MapType(keyType = StringType, valueType = IntegerType), true) :: Nil)
} override def dataType: DataType = StringType override def deterministic: Boolean = false //初始化map
override def initialize(buffer: MutableAggregationBuffer): Unit = {
buffer() = scala.collection.immutable.Map[String, Int]()
} //如果包含这个key则value+1,否则写入key,value=1
override def update(buffer: MutableAggregationBuffer, input: Row): Unit = {
val key = input.getAs[String]()
val immap = buffer.getAs[Map[String, Int]]()
val bufferMap = scala.collection.mutable.Map[String, Int](immap.toSeq: _*)
val ret = if (bufferMap.contains(key)) {
// val new_value = bufferMap.get(key).get + 1
val new_value = bufferMap(key) +
bufferMap.put(key, new_value)
bufferMap
} else {
bufferMap.put(key, )
bufferMap
}
buffer.update(, ret) } override def merge(buffer1: MutableAggregationBuffer, buffer2: Row): Unit = {
//合并两个map 相同的key的value累加
val tempMap = (buffer1.getAs[Map[String, Int]]() /: buffer2.getAs[Map[String, Int]]()) {
case (map, (k, v)) => map + (k -> (v + map.getOrElse(k, )))
}
buffer1.update(, tempMap)
} override def evaluate(buffer: Row): Any = {
//返回值最大的key
var max_value =
var max_key = ""
buffer.getAs[Map[String, Int]]().foreach({ x =>
val key = x._1
val value = x._2
if (value > max_value) {
max_value = value
max_key = key
}
})
max_key
}
}
测试类:
object UDAFTest {
def main(args: Array[String]): Unit = {
val spark = SparkSession.builder().master("local").appName(this.getClass.getSimpleName).getOrCreate()
spark.udf.register("get_mode", new UDAFGetMode)
import spark.implicits._
val df = Seq(
(, "10.10.1.1", "start"),
(, "10.10.1.1", "search"),
(, "123.123.123.1", "search"),
(, "10.10.1.0", "stop"),
(, "123.123.123.1", "start")
).toDF("id", "ip", "action")
df.createTempView("tb")
spark.sql(s"select id,get_mode(ip) as u_ip,count(*) as cnt from tb group by id").show()
}
}
UDAF(用户自定义聚合函数)求众数的更多相关文章
- Spark SQL 用户自定义函数UDF、用户自定义聚合函数UDAF 教程(Java踩坑教学版)
在Spark中,也支持Hive中的自定义函数.自定义函数大致可以分为三种: UDF(User-Defined-Function),即最基本的自定义函数,类似to_char,to_date等 UDAF( ...
- hive学习笔记之十:用户自定义聚合函数(UDAF)
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 本文是<hive学习笔记>的第十 ...
- 【Spark篇】---SparkSQL中自定义UDF和UDAF,开窗函数的应用
一.前述 SparkSQL中的UDF相当于是1进1出,UDAF相当于是多进一出,类似于聚合函数. 开窗函数一般分组取topn时常用. 二.UDF和UDAF函数 1.UDF函数 java代码: Spar ...
- 【Spark-SQL学习之三】 UDF、UDAF、开窗函数
环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 jdk1.8 scala-2.10.4(依赖jdk1.8) spark ...
- SQL Server 2008 R2——PIVOT 行转列 以及聚合函数的选择
==================================声明================================== 本文原创,转载在正文中显要的注明作者和出处,并保证文章的完 ...
- 2、SQL基础整理(聚合函数)
聚合函数 --求平均 select AVG(age) as 年龄 from xuesheng select AVG(chinese) as 语文 from xuesheng where class ...
- Hive学习之自己定义聚合函数
Hive支持用户自己定义聚合函数(UDAF),这样的类型的函数提供了更加强大的数据处理功能. Hive支持两种类型的UDAF:简单型和通用型.正如名称所暗示的,简单型UDAF的实现很easy,但因为使 ...
- Kafka:ZK+Kafka+Spark Streaming集群环境搭建(十五)Spark编写UDF、UDAF、Agg函数
Spark Sql提供了丰富的内置函数让开发者来使用,但实际开发业务场景可能很复杂,内置函数不能够满足业务需求,因此spark sql提供了可扩展的内置函数. UDF:是普通函数,输入一个或多个参数, ...
- Mongodb学习笔记四(Mongodb聚合函数)
第四章 Mongodb聚合函数 插入 测试数据 ;j<;j++){ for(var i=1;i<3;i++){ var person={ Name:"jack"+i, ...
随机推荐
- java语言的优缺点
转载自:https://blog.csdn.net/bingshanyijiao_fkx/article/details/51613954 角度一: 优点:简单.安全.稳定.跨平台 缺点:需要运行环境 ...
- Wifi OKC 验证
OKC(Opportunistic Key Caching) OKC,也叫OPC(Opportunistic PMK Caching),是微软定义的一套标准,并不在802.11标准中.不过多数厂商都支 ...
- 终于把eShopOnContainer部署成功了。
先上图说明一下,然后把步骤一部一部写上来吧.
- 如何查看SQL SERVER数据库当前连接数
SELECT * FROM[Master].[dbo].[SYSPROCESSES] WHERE [DBID] IN ( SELECT [DBID]FROM [Master].[dbo].[SYSDA ...
- dos 打开计算机管理
一. 首先打开[运行]程序:二. 运行中输入‘CMD’:三. 然后在上面输入‘compmgmt.msc’,就可以打开“计算机管理”命令了.
- Windows10 + IntelliJ IDEA 2017.3.2 + wamp2e + Yii + PHPunit 搭建测试环境
一.环境 系统: windows10 WampServer: wampserver2.2e-php5.3.13-httpd2.2.22-mysql5.5.24-32b.exe IDE: Intel ...
- 垃圾wps弹出,现在连关闭按钮都不给了
垃圾wps弹出,现在连关闭按钮都不给了,有点起色就变得相当垃圾.
- 初学UML之-------用例图
本文转载至:http://blog.csdn.net/a649518776/article/details/7493148 一.UML简介 UML(统一建模语言,Unified Modeling L ...
- 【分布式系列】session跨域及单点登录解决方案
Cookie机制 Cookie技术是客户端的解决方案,Cookie就是由服务器发给客户端的特殊信息,而这些信息以文本文件的方式存放在客户端,然后客户端每次向服务器发送请求的时候都会带上这些特殊的信息. ...
- centos6上调整lv逻辑卷
author:headsen chen date:2019-03-18 14:48:17 1,查看分区状态,发现/ 分区不够用./home分区太大了.浪费 [root@localhost ~]# d ...