Spark 定义UDF函数

SparkSQL定义UDF函数

无论Hive还是SparkSQL分析处理数据时,往往需要使用函数,SparkSQL模块本身自带很多实现公共功能的函数,在pyspark.sql.functions中。
SparkSQL与Hive一样支持定义函数:UDF和UDAF,尤其是UDF函数在实际项目中使用最为广泛。
回顾Hive中自定义函数有三种类型:

  • 第一种:UDF(User-Defined-Function)函数。
    – 一对一的关系,输入一个值经过函数以后输出一个值;
    – 在Hive中继承UDF类,方法名称为evaluate,返回值不能为void,其实就是实现一个方法;
  • 第二种:UDAF(User-Defined Aggregation Function)聚合函数
    – 多对一的关系,输入多个值输出一个值,通常与groupBy!联合使用;
  • 第三种:UDTF(User-Defined Table-Generating Functions)函数。
    – 一对多的关系,输入一个值输出多个值(一行变为多行);
    – 用户自定义生成函数,有点像flatMap;

目前spark对各语言的UDF定义支持:python目前只支持udf,但可以通过结合mapPartitions模拟UDTF
在这里插入图片描述

UDF函数定义方式

  1. sparksession.udf.register()
  • 注册的UDF可以用于DSL和SQL
  • 返回值用于DSL风格,传参内给的名字用于SQL风格
# encoding:utf8
import ..
if __name__ == '__main__':
    #O.构建执行环境入口对象SparkSession
    spark = SparkSession.builder.\
        appName("test").\
        master("local[*]").\
        config("spark.sql.shuffle.partitions",2).\
        getorCreate()
    sc = spark.sparkContext
    #构建—个RDD
    rdd = sc.parallelize([1,2,3,4,5,6,7]).map(lambda x:[x])
    df = rdd.toDF(["num"])
    #TOD01:方式1 sparksession,udf.register(O),DSL和SQL风格均可以使用
    #UDF的处理函数
    def num_ride_10(num):
        return num 10
    #参数1:注册的UDF的名称,这个Udf名称,仅可以用于SQL风格
    #参数2:UDF的处理逻辑,是一个单独的方法
    #参数3:声明UDF的返回值类型,注意:UDF注册时候,必须声明返回值类型,并豆UDF的真实返回值一定要和声明的返回值一致
    #返回值对象:这是一个UDF对象,仅可以用于DSL语法
    #当前这种方式定义的UDF,可以通过参数1的名称用于SQL风格,通过返回值对象用广DSL格
    udf2 = spark.udf.register("udf1",num_ride_10,IntegerType())
    #SQL风格中使用
    #selectExpr以SELECT的表达式执行,表达式SQL风格的表达式,该方法只接受字符串形式参数
    #select方法,接受普通的宁符串字段名,或者返回值是Column对象的计算
    df.selectExpr("udf1(num)").show)
    #DSL风格中使用
    #返回值UDF对象如果作为方法使用,传入的参数一定是Column对象
    df.select(udf2(df['num'])).show()

上面udf2变量只是一个命名

  1. pyspark.sql.functions.udf
    仅能用于DSL风格
#T0D02:方式2注册,仅能用于DSL风格
udf3 = F.udf(num_ride_10, IntegerType())
df.select(udf3(df[num'])).show()

SparkSQL定义UDF函数

注册一个ArrayType(数字\list)类型的返回值UDF

rdd = sc.parallelize(["hadoop spark flink"],["hadoop flink java"]])
df = rdd.toDF(["line"])
#T0D0方式1注册
#注册UDF,功能:将数字都乘以10
def split_line(line):
   return line.split("")
#返回值用于DSL风格
内部注册的名称用于SQL(字符串表达式)风格
udf2 = spark.udf.register("udf1", split_line, ArrayType(StringType()))
df.select(udf2(df ['line'])).show()
#select udf1(num)
df.selectExpr("udf1(line)").show()
#T0D0方式2注册,仅能用DSL风格
udf3 = F.udf(split_line, ArrayType(StringType()))
# 这里truncate设置为false不限制只展示20个字符
df.select(udf3(df['line'])).show(truncate=False)

注意:数组或者list类型,可以使用spark的ArrayType来描述即可.
注意:声明ArrayType要类似这样:ArrayType(StringType()),在ArrayType中传入数组内的数据类型

SparkSQL定义UDF函数

注册一个字典类型的返回值的UDF

rdd sc.parallelize([[1],[2],[3]])
df = rdd.toDF(["num"])
#T0D0方式1注册
#注册UDF,功能:将数字都乘以10
def split_line(num):
    return {"num":num, "letter str":string.ascii_letters [num]}
struct_type = StructType().add("num", IntegerType(), nullable=True).\
add("letter_str",StringType(),nullable=True)
#返回值用于DSL风格内部注册的名称用于SQL(字符串表达式)风格
udf2 = spark.udf.register("udf1", split_line, struct_type)
df.select(udf2(df(([num'])).show()
select udf1(num)
df.selectExpr("udf1(num)").show()
#T0D0方式2注册,仅能用DSL风格
udf3 F.udf(split_line, struct_type)
df.select(udf3(df(([num'])).show(truncate=False)

注意:字典类型返回值,可以用StructType来进行描述
StructType是一个普通的Spark支持的结构化类型
只是可以用在:
DF中用于描述Schema
UDF中用于描述返回值是字典的数据

  • 30
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值