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 小时前
DualPLP 双重掉电保护赋能 天硕工业级SSD筑牢关键领域安全存储方案
大数据·人工智能·安全·固态硬盘
雷文成.思泉软件3 小时前
以ERP为核心、企微为门户,实现一体化集成
大数据·低代码·创业创新
San30.4 小时前
深入理解 JavaScript 异步编程:从 Ajax 到 Promise
开发语言·javascript·ajax·promise
东哥说-MES|从入门到精通5 小时前
数字化部分内容 | 十四五年规划和2035年远景目标纲要(新华社正式版)
大数据·人工智能·数字化转型·mes·数字化工厂·2035·十四五规划
南飞测绘视界6 小时前
上市公司绿色专利申请、授权数据(1999-2024年)
大数据·专利·上市公司
一个天蝎座 白勺 程序猿7 小时前
KingbaseES在政务领域的应用实践——武汉人社大数据平台“数字化服务新模式”
大数据·数据库·政务·kingbasees·金仓数据库
pale_moonlight7 小时前
十、 Scala 应用实践 (上)
大数据·开发语言·scala
第二只羽毛8 小时前
遵守robots协议的友好爬虫
大数据·爬虫·python·算法·网络爬虫
Elastic 中国社区官方博客8 小时前
使用 A2A 协议和 MCP 在 Elasticsearch 中创建一个 LLM agent 新闻室:第二部分
大数据·数据库·人工智能·elasticsearch·搜索引擎·ai·全文检索
安达发公司8 小时前
安达发|告别手工排产!车间排产软件成为中央厨房的“最强大脑”
大数据·人工智能·aps高级排程·aps排程软件·安达发aps·车间排产软件