前言

本文介绍如何在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. Windows注册表的学习

    什么是注册表 注册表是Windows在Win95/98系统开始引入的一种核心数据库,里面存放着各类的配置信息.参数等.直接控制着系统的启动.硬件的装载以及Winodws程序的运行 手册表的功能 记录用 ...

  2. 使用poi实现生成excel文件

    import java.util.ArrayList; import javax.servlet.ServletOutputStream; import org.apache.poi.hssf.use ...

  3. 梯度下降:SGD vs Momentum vs NAG vs Adagrad vs Adadelta vs RMSprop vs Adam

    原文地址:https://www.jianshu.com/p/7a049ae73f56 梯度下降优化基本公式:\({\theta\leftarrow\theta-\eta\cdot\nabla_\th ...

  4. CodeForces-1249D2-Too Many Segments (hard version) -STL+贪心

    The only difference between easy and hard versions is constraints. You are given nn segments on the ...

  5. 使用CSS将图片转换成黑白(灰色、置灰) & 毛玻璃效果

    法1⃣️: IE浏览器: filter: gray; 其他浏览器: .gray { -webkit-filter: grayscale(100%); -moz-filter: grayscale(10 ...

  6. Day 22: 软件开发目录设计规范

    软件开发目录设计 对于提高项目可读性.可维护性的要求就很高了.”项目目录结构”其实也是属于”可读性和可维护性”的范畴,我们设计一个层次清晰的目录结构,就是为了达到以下两点: 可读性高: 不熟悉这个项目 ...

  7. css3继承

    不可继承的:display.margin.border.padding.background.height.min-height.max- height.width.min-width.max-wid ...

  8. pytest的断言、跳过、运行的按需要处理

    def test_one(): assert 1==1 assert 1!=2 assert {'name':'linda','age':19}=={'name':'linda','age':190} ...

  9. JS变量1

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  10. 了解GTIN小记

    GTIN为条形码,即"全球贸易项目代码"(Global Trade Item Number ) GTIN用作识别商品品项的全球性独一编码,是编码系统中应用最广泛的标识代码. GTI ...