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)
相关推荐
weikecms19 分钟前
外卖霸王餐API接口对接
大数据·人工智能·企业微信·微客云
captain_AIouo39 分钟前
Captain AI以数据为核心,打造OZON智能决策引擎
大数据·人工智能·经验分享·aigc
Aloudata1 小时前
AI 时代如何通过主动元数据构建高质量、可追溯的语义底座?
大数据·人工智能·数据治理·元数据·数据血缘
andafaAPS1 小时前
安达发|aps自动排产排程排单软件:日化生产高效运转“数字魔法”
大数据·人工智能·算法·aps软件·安达发aps·aps自动排产排程排单软件
黎阳之光1 小时前
全域实景立体管控:数字孪生与视频孪生技术体系白皮书
大数据·人工智能·算法·安全·数字孪生
2301_815645382 小时前
异步编程(axios)
ajax
龙亘川2 小时前
城市更新×智慧治理:老旧小区改造中的数字化创新实践
java·大数据·人工智能·机器学习·智慧城市
飞函安全2 小时前
法务、人资、财务共用协同平台时,怎样避免权限串线和资料误传
大数据·安全·私有化im
workflower2 小时前
农业信息化
大数据·人工智能·设计模式·机器人·软件工程
倔强的石头1063 小时前
告别昂贵的ETL——大数据架构下的时序选型指南
大数据·架构·etl