前言

本文介绍如何在Spark Sql和DataFrame中使用UDF,如何利用UDF给一个表或者一个DataFrame根据需求添加几列,并给出了旧版(Spark1.x)和新版(Spark2.x)完整的代码示例。

关于UDF:UDF:User Defined Function,用户自定义函数

创建测试用DataFrame

spark2.0创建DataFrame

// 构造测试数据,有两个字段、名字和年龄
val userData = Array(("A", ), ("B", ), ("B", ), ("B", )) //创建测试df
val userDF = spark.createDataFrame(userData).toDF("name", "age")
userDF.show
+-----+---+
| name|age|
+-----+---+
| A | 16|
| B | 21|
| C | 14|
| D | 18|
+-----+---+
// 注册一张user表 
userDF.createOrReplaceTempView("user")

spark1.0创建DataFrame

 // 构造测试数据,有两个字段、名字和年龄
val userData = Array(("A", ), ("B", ), ("C", ), ("D", ))
//创建测试df
val userDF = sc.parallelize(userData).toDF("name", "age")
// 注册一张user表
userDF.registerTempTable("user")

spark-sql中SQL中UDF用法

1. 通过匿名函数注册UDF

下面的UDF的功能是计算某列的长度,该列的类型为String

// Spark2.x:
spark.udf.register("strLen", (str: String) => str.length()) // Spark1.x:
sqlContext.udf.register("strLen", (str: String) => str.length()) // 仅以Spark2.x为例
spark.sql("select name,strLen(name) as name_len from user").show

2. 通过实名函数注册UDF

实名函数的注册有点不同,要在后面加 _(注意前面有个空格)

// 定义一个实名函数

/**
* 根据年龄大小返回是否成年 成年:true,未成年:false
*/
def isAdult(age: Int) = {
if (age < ) {
false
} else {
true
}
} // 注册(仅以Spark2.x为例)
spark.udf.register("isAdult", isAdult _)

spark-sql中DataFrame中UDF用法

DataFrame的udf方法虽然和Spark Sql的名字一样,但是属于不同的类,它在org.apache.spark.sql.functions里,下面是它的用法

1. 注册

import org.apache.spark.sql.functions._
//方法一:注册自定义函数(通过匿名函数)
val strLen = udf((str: String) => str.length()) //方法二:注册自定义函数(通过实名函数)
val udf_isAdult = udf(isAdult _)

2. 使用

可通过withColumn和select使用,下面的代码已经实现了给user表添加两列的功能 
* 通过看源码,下面的withColumn和select方法Spark2.0.0之后才有的,关于spark1.xDataFrame怎么使用注册好的UDF没有研究

// 通过withColumn添加列
userDF.withColumn("name_len", strLen(col("name"))).withColumn("isAdult", udf_isAdult(col("age"))).show //通过select添加列
userDF.select(col("*"), strLen(col("name")) as "name_len", udf_isAdult(col("age")) as "isAdult").show +-----+---+--------+-------+
| name|age|name_len|isAdult|
+-----+---+--------+-------+
| A | | | false|
| B | | | true|
| C | | | false|
| D | | | true|
+-----+---+--------+-------+

withColumn和select的区别

可通过withColumn的源码看出withColumn的功能是实现增加一列,或者替换一个已存在的列,他会先判断DataFrame里有没有这个列名,如果有的话就会替换掉原来的列,没有的话就用调用select方法增加一列,所以如果我们的需求是增加一列的话,两者实现的功能一样,且最终都是调用select方法,但是withColumn会提前做一些判断处理,所以withColumn的性能不如select好。

注:select方法和sql 里的select一样,如果新增的列名在表里已经存在,那么结果里允许出现两列列名相同但数据不一样,大家可以自己试一下。

参考:https://dongkelun.com/2018/08/02/sparkUDF/

spark自定义函数之——UDF使用详解及代码示例的更多相关文章

  1. spark自定义函数之——UDAF使用详解及代码示例

    UDAF简介 UDAF(User Defined Aggregate Function)即用户定义的聚合函数,聚合函数和普通函数的区别是什么呢,普通函数是接受一行输入产生一个输出,聚合函数是接受一组( ...

  2. laravel 框架配置404等异常页面的方法详解(代码示例)

    本篇文章给大家带来的内容是关于laravel 框架配置404等异常页面的方法详解(代码示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 在Laravel中所有的异常都由Handl ...

  3. Spark 自定义函数(udf,udaf)

    Spark 版本 2.3 文中测试数据(json) {"name":"lillcol", "age":24,"ip":& ...

  4. php自定义函数call_user_func和call_user_func_array详解

    看UCenter的时候有一个函数call_user_func,百思不得其解,因为我以为是自己定义的函数,结果到处都找不到,后来百度了一下才知道call_user_func是内置函 call_user_ ...

  5. c/c++中define用法详解及代码示例

    https://blog.csdn.net/u012611878/article/details/52534622   版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog. ...

  6. PCA 降维算法详解 以及代码示例

    转载地址:http://blog.csdn.net/watkinsong/article/details/38536463 1. 前言 PCA : principal component analys ...

  7. 大数据学习day29-----spark09-------1. 练习: 统计店铺按月份的销售额和累计到该月的总销售额(SQL, DSL,RDD) 2. 分组topN的实现(row_number(), rank(), dense_rank()方法的区别)3. spark自定义函数-UDF

    1. 练习 数据: (1)需求1:统计有过连续3天以上销售的店铺有哪些,并且计算出连续三天以上的销售额 第一步:将每天的金额求和(同一天可能会有多个订单) SELECT sid,dt,SUM(mone ...

  8. JS函数动作分层结构详解及Document.getElementById 释义 js及cs数据类型区别 事件 函数 变量 script标签 var function

    html +css 静态页面 js     动态 交互   原理: js就是修改样式, 比如弹出一个对话框. 弹出的过程就是这个框由disable 变成display:enable. 又或者当鼠标指向 ...

  9. Wordpress菜单函数wp_nav_menu各参数详解及示例

    Wordpress菜单函数wp_nav_menu各参数详解及示例   注册菜单 首先要注册菜单,将以下函数添加至function.php函数里   register_nav_menus(array( ...

随机推荐

  1. Sqli labs系列-less-4 这关好坑!!!

    这章,可能我总结开会比较长,图比较多,因为,我在做了一半,走进了一个死胡同,脑子,一下子没想开到底为啥.... 然后我自己想了好长时间也没想开,我也不想直接就去看源码,所以就先去百度了一下,结果一下子 ...

  2. TeleportArea可瞬移的目标位置

    TeleportArea.png 1.可以自定义mesh ,想要什么区域就可以设置什么区域的mesh网格.2.Collider 组件必须有,否则无法进行位置移动,它用来检测激光笔是否打到该区域.3.M ...

  3. Java-框架-Dubbo:Dubbo

    ylbtech-Java-框架-Dubbo:Dubbo Dubbo是阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和Spring框架无缝集成 ...

  4. 前台处理ajax:axios

    """ 1.安装axios cnpm install axios --save 2.src/main.js配置 // 允许ajax发送请求时附带cookie axios. ...

  5. 3. 初识jmeter及JDK安装

    jmeter 介绍 Apache JMeter™应用程序是开源软件,100%纯Java应用程序,旨在加载测试功能行为和测量性能.它最初是为测试Web应用程序而设计的,但后来扩展到其他测试功能. Jme ...

  6. 剑指offer——66翻转字符串

    题目描述 牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上.同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思.例如,“student ...

  7. 剑指offer——56在排序数组中查找数字

    题目描述 统计一个数字在排序数组中出现的次数.   题解: 使用二分法找到数k然后向前找到第一个k,向后找到最后一个k,即可知道有几个k了 但一旦n个数都是k时,这个方法跟从头遍历没区别,都是O(N) ...

  8. 线性回归——Python代码实现

    import numpy as np def computer_error_for_give_point(w, b, points): # 计算出 观测值与计算值 之间的误差, 并累加,最后返回 平均 ...

  9. swagger2 注解说明 ( @ApiImplicitParams )

    @Api:用在请求的类上,表示对类的说明 tags="说明该类的作用,可以在UI界面上看到的注解" value="该参数没什么意义,在UI界面上也看到,所以不需要配置&q ...

  10. UTF-8 - ASCII 兼容的多字节 Unicode 编码

    描述 The Unicode 字符集使用的是 16 位(双字节)码.最普遍的 Unicode 编码方法( UCS-2) 由一个 16 位双字序列组成.这样的字符串中包括了的一些如‘\0’或‘/’这样的 ...