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)
相关推荐
Lx3523 小时前
复杂MapReduce作业设计:多阶段处理的最佳实践
大数据·hadoop
武子康6 小时前
大数据-100 Spark DStream 转换操作全面总结:map、reduceByKey 到 transform 的实战案例
大数据·后端·spark
expect7g7 小时前
Flink KeySelector
大数据·后端·flink
阿里云大数据AI技术1 天前
StarRocks 助力数禾科技构建实时数仓:从数据孤岛到智能决策
大数据
Lx3521 天前
Hadoop数据处理优化:减少Shuffle阶段的性能损耗
大数据·hadoop
武子康1 天前
大数据-99 Spark Streaming 数据源全面总结:原理、应用 文件流、Socket、RDD队列流
大数据·后端·spark
阿里云大数据AI技术2 天前
大数据公有云市场第一,阿里云占比47%!
大数据
Lx3522 天前
Hadoop容错机制深度解析:保障作业稳定运行
大数据·hadoop
计算机毕业设计木哥2 天前
计算机毕设选题推荐:基于Java+SpringBoot物品租赁管理系统【源码+文档+调试】
java·vue.js·spring boot·mysql·spark·毕业设计·课程设计
T06205142 天前
工具变量-5G试点城市DID数据(2014-2025年
大数据