spark自定义函数实现

场景:由于系统函数无法满足实际开发需求,需要通过自定义函数来实现

示例:

scala 复制代码
package spark

import org.apache.spark.sql.{Row, SparkSession}
import org.apache.spark.sql.expressions.{MutableAggregationBuffer, UserDefinedAggregateFunction}
import org.apache.spark.sql.types.{DataType, LongType, StructField, StructType}

object TestSparkUdf {
  def main(args: Array[String]): Unit = {
    val spark = SparkSession
      .builder()
      .appName("student")
      .master("local[2]")
      .getOrCreate()
    import spark.implicits._
    val rdd2 = spark.sparkContext.makeRDD(Array(Student2(18, "one"), Student2(20, "two")))
    rdd2.toDF().registerTempTable("student")

    spark.udf.register("myupper", myUpper _)
    val df = spark.sql("select myupper(name) from student")
    df.show()
//    +-----------------+
//    |UDF:myupper(name)|
//    +-----------------+
//    |              ONE|
//    |              TWO|
//    +-----------------+
    spark.udf.register("myavg", new myAvg())
    val df2 = spark.sql("select myavg(age) from student")
    df2.show()
//    +----------+
//    |myavg(age)|
//    +----------+
//    |        19|
//    +----------+
    spark.stop()

  }

  //udf函数 一对一
  def myUpper(str: String): String = str.toUpperCase()

}
//case class Student(id: String, name:String)

class myAvg extends UserDefinedAggregateFunction {
  //输入数据的结构
  override def inputSchema: StructType = StructType(Array(StructField("age", LongType)))
  //缓冲区的数据结构
  override def bufferSchema: StructType = StructType(Array(StructField("total", LongType), StructField("count", LongType)))
  //函数计算结果的数据类型
  override def dataType: DataType = LongType
  //函数的稳定性
  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.update(0, buffer.getLong(0) + input.getLong(0))
    buffer.update(1, buffer.getLong(1) + 1)
  }
  //多个缓冲区数据合并
  override def merge(buffer1: MutableAggregationBuffer, buffer2: Row): Unit = {
    buffer1.update(0, buffer1.getLong(0) + buffer2.getLong(0))
    buffer1.update(1, buffer1.getLong(1) + buffer2.getLong(1))
  }
  //计算操作结果
  override def evaluate(buffer: Row): Any = {
    buffer.getLong(0) / buffer.getLong(1)
  }
}

case class Student2(age: Long, name: String)
相关推荐
金融小师妹3 小时前
多因子智能推演:油价回落6%与黄金震荡上行的关联解析——AI预测框架
大数据·python·深度学习
IanSkunk5 小时前
眼视光中心设备互联与数据安全:从设备采购到患者数字档案的合规路径
大数据
重庆传粉科技5 小时前
AI搜索重构互联网价值交换:GEO如何缓解全域流量流失难题
大数据·人工智能
专注数据的痴汉6 小时前
「数据下载」黑龙江省黑土区富锦市土地利用数据
大数据·人工智能·信息可视化
互联网中的一颗神经元8 小时前
09 — .git 地图:打开那个隐藏文件夹
大数据·git·elasticsearch
zyplayer-doc9 小时前
zyplayer-doc企业知识库能做什么:从文档创建、权限管理到AI问答的完整能力
大数据·javascript·数据库·人工智能·pdf·word
今天AI了吗10 小时前
精细化落地教程:TimechoAI调参标准+数据清洗规范+误差归因+阈值适配全维度指南
大数据·人工智能·算法
明源云10 小时前
资产管理软件哪个好?不动产资产管理系统的选型逻辑与标杆实践
大数据·人工智能·架构
独行侠影a11 小时前
Elasticsearch海量数据查询优化:深度分页与聚合查询提速方案
大数据·elasticsearch·搜索引擎