一、UDF

1、UDF

UDF:User Defined Function。用户自定义函数。

2、scala案例

package cn.spark.study.sql

import org.apache.spark.SparkConf
import org.apache.spark.SparkContext
import org.apache.spark.sql.SQLContext
import org.apache.spark.sql.Row
import org.apache.spark.sql.types.StructType
import org.apache.spark.sql.types.StructField
import org.apache.spark.sql.types.StringType object UDF {
def main(args: Array[String]): Unit = {
val conf = new SparkConf().setMaster("local").setAppName("UDF")
val sc = new SparkContext(conf)
val sqlContext = new SQLContext(sc) // 构造模拟数据
val names = Array("Leo", "Marry", "Jack", "Tom")
val namesRDD = sc.parallelize(names, 5)
val namesRowRDD = namesRDD.map(name => Row(name))
val structType = StructType(Array(StructField("name", StringType, true)))
val namesDF = sqlContext.createDataFrame(namesRowRDD, structType) // 注册一张names表
namesDF.registerTempTable("names") // 定义和注册自定义函数
// 定义函数:自己写匿名函数
// 注册函数:SQLContext.udf.register()
// UDF函数名:strLen; 函数体(匿名函数):(str: String) => str.length()
sqlContext.udf.register("strLen", (str: String) => str.length()) // 使用自定义函数
sqlContext.sql("select name, strLen(name) from names")
.collect()
.foreach(println) }
}

3、java案例

package cn.spark.study.sql;

import java.util.ArrayList;
import java.util.List; import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.Function;
import org.apache.spark.api.java.function.VoidFunction;
import org.apache.spark.sql.DataFrame;
import org.apache.spark.sql.Row;
import org.apache.spark.sql.RowFactory;
import org.apache.spark.sql.SQLContext;
import org.apache.spark.sql.api.java.UDF1;
import org.apache.spark.sql.types.DataTypes;
import org.apache.spark.sql.types.StructField;
import org.apache.spark.sql.types.StructType; public class UDF {
public static void main(String[] args) {
SparkConf conf = new SparkConf().setAppName("UDFJava").setMaster("local");
JavaSparkContext sparkContext = new JavaSparkContext(conf);
SQLContext sqlContext = new SQLContext(sparkContext); List<String> stringList = new ArrayList<String>();
stringList.add("Leo");
stringList.add("Marry");
stringList.add("Jack");
stringList.add("Tom");
JavaRDD<String> rdd = sparkContext.parallelize(stringList);
JavaRDD<Row> nameRDD = rdd.map(new Function<String, Row>() { private static final long serialVersionUID = 1L; @Override
public Row call(String v1) throws Exception {
return RowFactory.create(v1);
}
}); List<StructField> fieldList = new ArrayList<StructField>();
fieldList.add(DataTypes.createStructField("name", DataTypes.StringType, true));
StructType structType = DataTypes.createStructType(fieldList);
DataFrame dataFrame = sqlContext.createDataFrame(nameRDD, structType); dataFrame.registerTempTable("name");
sqlContext.udf().register("strLen", new UDF1<String, Integer>() { private static final long serialVersionUID = 1L; @Override
public Integer call(String s) throws Exception {
// TODO Auto-generated method stub
return s.length();
} }, DataTypes.IntegerType); sqlContext.sql("select name, strLen(name) from name").javaRDD().
foreach(new VoidFunction<Row>() { private static final long serialVersionUID = 1L; @Override
public void call(Row row) throws Exception {
System.out.println(row);
}
}); }
}

二、UDAF

1、概述

UDAF:User Defined Aggregate Function。用户自定义聚合函数。是Spark 1.5.x引入的最新特性。

UDF,其实更多的是针对单行输入,返回一个输出,这里的UDAF,则可以针对一组(多行)输入,进行聚合计算,返回一个输出,功能更加强大
使用:

1. 自定义类继承UserDefinedAggregateFunction,对每个阶段方法做实现

2. 在spark中注册UDAF,为其绑定一个名字

3. 然后就可以在sql语句中使用上面绑定的名字调用

2、scala案例

统计字符串次数的例子,先定义一个类继承UserDefinedAggregateFunction:

package cn.spark.study.sql

import org.apache.spark.sql.expressions.UserDefinedAggregateFunction
import org.apache.spark.sql.types.StructType
import org.apache.spark.sql.types.DataType
import org.apache.spark.sql.expressions.MutableAggregationBuffer
import org.apache.spark.sql.Row
import org.apache.spark.sql.types.StructField
import org.apache.spark.sql.types.StringType
import org.apache.spark.sql.types.IntegerType /**
* @author Administrator
*/
class StringCount extends UserDefinedAggregateFunction { // inputSchema,指的是,输入数据的类型
def inputSchema: StructType = {
StructType(Array(StructField("str", StringType, true)))
} // bufferSchema,指的是,中间进行聚合时,所处理的数据的类型
def bufferSchema: StructType = {
StructType(Array(StructField("count", IntegerType, true)))
} // dataType,指的是,函数返回值的类型
def dataType: DataType = {
IntegerType
} def deterministic: Boolean = {
true
} // 为每个分组的数据执行初始化操作
def initialize(buffer: MutableAggregationBuffer): Unit = {
buffer(0) = 0
} // 指的是,每个分组,有新的值进来的时候,如何进行分组对应的聚合值的计算
def update(buffer: MutableAggregationBuffer, input: Row): Unit = {
buffer(0) = buffer.getAs[Int](0) + 1
} // 由于Spark是分布式的,所以一个分组的数据,可能会在不同的节点上进行局部聚合,就是update
// 但是,最后一个分组,在各个节点上的聚合值,要进行merge,也就是合并
def merge(buffer1: MutableAggregationBuffer, buffer2: Row): Unit = {
buffer1(0) = buffer1.getAs[Int](0) + buffer2.getAs[Int](0)
} // 最后,指的是,一个分组的聚合值,如何通过中间的缓存聚合值,最后返回一个最终的聚合值
def evaluate(buffer: Row): Any = {
buffer.getAs[Int](0)
} }

然后注册并使用它:

package cn.spark.study.sql

import org.apache.spark.SparkConf
import org.apache.spark.SparkContext
import org.apache.spark.sql.SQLContext
import org.apache.spark.sql.Row
import org.apache.spark.sql.types.StructType
import org.apache.spark.sql.types.StructField
import org.apache.spark.sql.types.StringType /**
* @author Administrator
*/
object UDAF { def main(args: Array[String]): Unit = {
val conf = new SparkConf()
.setMaster("local")
.setAppName("UDAF")
val sc = new SparkContext(conf)
val sqlContext = new SQLContext(sc) // 构造模拟数据
val names = Array("Leo", "Marry", "Jack", "Tom", "Tom", "Tom", "Leo")
val namesRDD = sc.parallelize(names, 5)
val namesRowRDD = namesRDD.map { name => Row(name) }
val structType = StructType(Array(StructField("name", StringType, true)))
val namesDF = sqlContext.createDataFrame(namesRowRDD, structType) // 注册一张names表
namesDF.registerTempTable("names") // 定义和注册自定义函数
// 定义函数:自己写匿名函数
// 注册函数:SQLContext.udf.register()
sqlContext.udf.register("strCount", new StringCount) // 使用自定义函数
sqlContext.sql("select name,strCount(name) from names group by name")
.collect()
.foreach(println)
} }

45、sparkSQL UDF&UDAF的更多相关文章

  1. 简述UDF/UDAF/UDTF是什么,各自解决问题及应用场景

    UDF User-Defined-Function 自定义函数 .一进一出: 背景 系统内置函数无法解决实际的业务问题,需要开发者自己编写函数实现自身的业务实现诉求. 应用场景非常多,面临的业务不同导 ...

  2. 45、[源码]-Spring容器创建-执行BeanFactoryPostProcessor

    45.[源码]-Spring容器创建-执行BeanFactoryPostProcessor 5.invokeBeanFactoryPostProcessors(beanFactory);执行BeanF ...

  3. Spark(十三)【SparkSQL自定义UDF/UDAF函数】

    目录 一.UDF(一进一出) 二.UDAF(多近一出) spark2.X 实现方式 案例 ①继承UserDefinedAggregateFunction,实现其中的方法 ②创建函数对象,注册函数,在s ...

  4. [转]HIVE UDF/UDAF/UDTF的Map Reduce代码框架模板

    FROM : http://hugh-wangp.iteye.com/blog/1472371 自己写代码时候的利用到的模板   UDF步骤: 1.必须继承org.apache.hadoop.hive ...

  5. 2、Hive UDF编程实例

    Hive的UDF包括3种:UDF(User-Defined Function).UDAF(User-Defined Aggregate Function)和UDTF(User-Defined Tabl ...

  6. Hive 自定义函数 UDF UDAF UDTF

    1.UDF:用户定义(普通)函数,只对单行数值产生作用: 继承UDF类,添加方法 evaluate() /** * @function 自定义UDF统计最小值 * @author John * */ ...

  7. 【转】HIVE UDF UDAF UDTF 区别 使用

    原博文出自于:http://blog.csdn.net/longzilong216/article/details/23921235(暂时) 感谢! 自己写代码时候的利用到的模板   UDF步骤: 1 ...

  8. SparkSQL之UDAF使用

    1.创建一个类继承UserDefinedAggregateFunction类. ------------------------------------------------------------ ...

  9. sparksql udf的运用----scala及python版(2016年7月17日前完成)

    问:udf在sparksql 里面的作用是什么呢? 答:oracle的存储过程会有用到定义函数,那么现在udf就相当于一个在sparksql用到的函数定义: 第二个问题udf是怎么实现的呢? regi ...

随机推荐

  1. helm chart应用使用示例

    有两种方法 一是按照正常流程直接用yaml文件的形式发布应用到k8s集群上 二是把生成好的yaml文件发布到kubeapps应用商店,在应用商店中操作发布应用到k8s集群中 这里采用第二种方式的变种方 ...

  2. Web SSH远程连接利器:gotty

    Web SSH远程连接利器:gotty 这个东东能让你使用浏览器连接你远程的机器! 一. 环境准备 下载https://github.com/yudai/gotty. 请先配置好 Golang 环境, ...

  3. java之struts2的数据处理

    这里的数据处理,指的是页面上的数据与Action中的数据的处理. struts2中有3种方式来接收请求提交的数据.分别是:属性驱动方式.对象驱动方式.模型驱动方式 1. 属性驱动方式 要求页面中的表单 ...

  4. Java序列化流

    1.什么是序列化流 序列化就是把Java对象“流化”,序列化后的Java对象可以保存到本地文件系统,或者通过Socket传输到其他的服务器. Java中对象序列化有以下特点: 1)类实现java.io ...

  5. iOS - 小功能 跳转到淘宝或天猫的商品展示详情页

    最近做iOS项目的时候遇到一个需求,点击广告页,跳转到淘宝或天猫的商品详情页. 具体需要是这样: 1)安装了淘宝:跳转到淘宝详情页. 2)没装淘宝,装了天猫:跳转到天猫详情页 3)淘宝.天猫都没装:跳 ...

  6. Java新功能之方法引用

    方法引用的使用 最初,引用只是针对引用类型完成的,也就是只有数组.类.接口才具备引用操作.JDK1.8后追加了方法引用.实际上引用的本质就是别名. 因此方法的引用就是别名的使用. 方法的引用有四种形式 ...

  7. Android笔记(六十八) Fragment总结

    Fragment的产生: 为了适应各种尺寸的屏幕,谷歌推出Fragment,可以把Fragment成Activity的一个组成部分,它拥有自己的生命周期.可以接收并处理用户的各种事件,还可以动态的增删 ...

  8. UVA572 (并查集解法)

    紫书第六章的题,用并查集重写一遍,果然还是书上给的dfs方法更简单...... 一开始用fa[i*m+j] != i*m+j 来判断是否访问过,虽然没想出来为什么WA,但是确实不如用vis稳 #inc ...

  9. python蟒蛇绘制的代码以及目前还不知道怎么用的RGB颜色对照表

    #PythonDraw.py import turtle#引入海龟库 turtle.setup(650,350,200,200)#确定窗口大小,长650,高350,确定窗口位置,距离电脑左上角200, ...

  10. Luogu P1196 银河英雄传说

    Luogu P1196 银河英雄传说 我们考虑用并查集来维护战舰的情况. 同时,我们用一个$d$数组来记录$x$与$fa[x]$之间的距离.再用$size$数组记录战舰当前所在列的战舰数. 易知两艘在 ...