前言

本文介绍如何在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. STM32时钟初始化函数SystemInit()详解【转】

    花了一天的时间,总算是了解了SystemInit()函数实现了哪些功能,初学STM32,,现记录如下(有理解错误的地方还请大侠指出): 使用的是3.5的库,用的是STM32F107VC,开发环境RVM ...

  2. jdk tomcat的项目版本一致操作

    操作jdk版本以及tomcat版本:右键项目--buildpath--configure buildpath...---project Facets---libraries---add/选中remov ...

  3. Ubuntu 没有 无线网 RTL8821ce 8111 8186

    1.将ubuntu的linux内核版本更改到4.14(其他版本不兼容这个无线网卡的驱动) 1.1 找到内核版本 #到 Ubuntu网站http://kernel.ubuntu.com/~kernel- ...

  4. Unity通过Jar包调用Android

    Unity通过Jar包调用Android 我们会需要面对下面几个问题,我们一个一个来解决: 怎样在Android Studio中打Jar包 怎样打一个Unity使用的Jar包 怎样在Unity工程中使 ...

  5. 【二叉树】二叉树常用算法的C++实现

    常见算法有: 1.求二叉树的最大深度 2.求二叉树的最小深度 3.二叉树的层次遍历 4.二叉树的前序遍历 5.二叉树的中序遍历 6.二叉树的后序遍历 7.求二叉树的节点个数 8.求二叉树的叶节点个数 ...

  6. FreeBSD_11-系统管理——{Part_a-bhyve}

    ;; 创建 vm: #!/usr/bin/env zsh bridgeIF=bridge0 laggIF=lagg0 tapIF=tap0 phyIF_0=re0 phyIF_1=em0 isoPat ...

  7. 拾遗:Qemu/KVM

    WinXP: #!/bin/bash name=winxp qemu-system-x86_64 \ -enable-kvm \ -cpu host -smp ,sockets=,cores=,thr ...

  8. python获取全部股票每日基本面指标,用于选股分析、报表展示等

    接口:daily_basic 更新时间:交易日每日15点-17点之间 描述:获取全部股票每日重要的基本面指标,可用于选股分析.报表展示等. 积分:用户需要至少300积分才可以调取,具体请参阅本文最下方 ...

  9. C#操作Word的+ CKEditor 輸出成Word文件(包含圖案上傳)

    C#操作Word 参考博文: C#操作word类文件 https://www.cnblogs.com/walking/p/3571068.html C#中的Office操作专栏(21) http:// ...

  10. margin与padding

    1.不加内边距的div: <div style="width:150px; height:150px; ">    <div style="width: ...