Spark UDF返回多列

Spark UDF返回多列或者称为UDTF

前言

对于UDF和UDAF相比大家并不陌生,用起来也都很顺手,在此就不多做介绍了~

通常我们的UDF都是一个或多个输入,然后一个输出。如果想要使用多个输出,比如像1.6版本里的json_tuple这样

df.select(json_tuple(col("jsonField"), "Field1", "Field2").as(Seq("Field1", "Field2")))

这种输出方式可以直接输出多列,同时 explode 也是类似的,这一类Spark内置函数称为 UDTF 也即 User Defined Table-generation Function,函数的输入是一个或多个列值,输出是一个table

不过Spark目前并未提供我们自己实现UDTF的方法,所以目前的使用还仅限于Spark内置的几个UDTF,想要达到多列输出,我们需要略作变通

使用Seq做返回类型,输出的多列是一个数组

def test: (String => Seq[String]) = aa => Seq("aa", aa, "cc")

这时候 udf(test) 的返回类型就是 ArrayType ,通过Column的getItem方法,我们可以取数得到多列

val testUDF = udf(test)
df.select(testUDF(col("testCol")).as("testUDFCol"))
  .select(col("testUDFCol").getItem(0).as("col1"),
    col("testUDFCol").getItem(1).as("col2"))

使用元组或case class做返回类型

case class Test(id: String, name: String)
def test: (String => Test) = aa => Test("1", aa)

// 使用元组做返回类型
def test: (String => (String, String)) = aa => ("1", aa)

当使用元组或case class做函数返回类型时,UDF的返回类型就是StructType,通过Column的getField方法,我们可以取数得到多列

val testUDF = udf(test)

df.select(testUDF(col("testCol")).as("testUDFCol"))
  .select(col("testUDFCol").getField("id").as("col1"),
    col("testUDFCol").getField("name").as("col2"))

 
// 使用元组的时候取值
df.select(testUDF(col("testCol")).as("testUDFCol"))
  .select(col("testUDFCol").getField("_1").as("col1"),
    col("testUDFCol").getField("_2").as("col2"))

使用Map作为返回类型

def test: (String => Map[String, String]) = aa => Map("id" -> "1", "name" -> aa)

对于Map类型,UDF的返回类型是MapType,也是通过Column的getField方法,我们可以取数得到多列

val testUDF = udf(test)

df.select(testUDF(col("testCol")).as("testUDFCol"))
  .select(col("testUDFCol").getField("id").as("col1"),
    col("testUDFCol").getField("name").as("col2"))

最后
想说的是,这种变通方式好像跟输出多列的UDF这个标题扯得有点远了,其实并没有输出多列,只是换一个类型而已,但问题由此引起,也就以此为题啦~~
另外,显然使用case class这种方式更好,因为返回类型有多种,更适合实际项目需要~~

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值