Spark UDF 使用中看似问题的问题

351次阅读
没有评论

这篇文章的由来是最近在做数据负采样方面的工作,看了些论文准备自己着手对样本直接操作,常规的使用工具就是Spark,日常工作中现在使用Spark的概率很高,做数据分析工作很有帮助。

以下描述涉及到Spark 默认版本 2.4  Scala 版本 2.11.8,可能有Java,如果有的话就是1.8

UDF 使用的场景都是在DataFrame 里面使用,日常都是基于Hive Hadoop文件或者Tfrecord 读取数据出来就是DataSet或者DataFrame。

先简单描述一下UDF的使用方法,在引出我想要说的问题。

使用UDF主要经历两个步骤

注册 ——–> 使用

1、注册

注册常用的有两个方法:

(1)基于匿名函数

(2)基于事先定义好的函数

两种方法的操作实例如下所示

spark.udf.register("test1", (str: String) => str.length())

事先定义好的函数

def test1(data: String) = { data.length } spark.udf.register("test1", test1 _)

 

Emmm 还是漏掉一种方案,直接操作的

val toUpperCase = functions.udf((str: String) => str.length())

使用

spark.sql("select name,test1(name) as name_len from user").show

或者在DataFrame中

userDF.withColumn("name_len", test1(col("name"))).show

以上就是展示了UDF的注册与使用了,OK 问题来了,注册的UDF 要么在SQL的字符串语法里或者对COL列操作,我们给的DEMO 只有一个参数,我现在需要加入第二个参数,而且是外部传参,不是对DataFrame列处理。

我自己实际传的是Map ,Scala Map放到sql字符串里就会出现解析失败的情况,因为Map的形式如下所示

Map(a->2,b->3)

这里面会有 -> 这个是sql无法解析的,所以在开始执行的时候就会包parse失败的错误。

还有一种直接是哟经UDF操作,但是它需要传入的其实是Col列,我试着使用lit对其转化,其实都会报错。

Spark So 最后的办法我是把要传的变量当做全局传到函数里去,然后在使用上述描述的方法实现,感觉还是不够优雅,但是能解决眼前的问题。

 

admin
版权声明:本站原创文章,由admin2020-12-05发表,共计990字。
转载提示:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)