如何在Scala udf中使用字符串数组作为参数?

时间:2017-06-30 10:48:24

标签: scala apache-spark

我的Spark数据框(从Hive表创建)看起来像:

+------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
|racist|filtered                                                                                                                                                      |
+------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+
|false |[rt, @dope_promo:, crew, beat, high, scores, fugly, frog, , https://time.com/sxp3onz1w8]                                                                      |
|false |[rt, @axolrose:, yall, call, kermit, frog, lizard?, , https://time.com/wdaeaer1ay]                                                                                |

我试图从过滤字段中删除网址。

我试过了:

val regex = "(https?\\://)\\S+".r

def removeRegex( input: Array[String] ) : Array[String]  = {
    regex.replaceAllIn(input, "")
}

val removeRegexUDF = udf(removeRegex)

filteredDF.withColumn("noURL", removeRegexUDF('filtered)).show

给出了这个错误:

<console>:60: error: overloaded method value replaceAllIn with alternatives:
  (target: CharSequence,replacer: scala.util.matching.Regex.Match => String)String <and>
  (target: CharSequence,replacement: String)String
 cannot be applied to (Array[String], String)
           regex.replaceAllIn(input, "")
                 ^

我是Scala的新手,所以您可以提供有关如何处理udf中已过滤数组的任何指导,我们非常感谢。 (或者如果有更好的方法,我很高兴听到它)。

2 个答案:

答案 0 :(得分:2)

我不会用空字符串替换URL,而是删除它们。这个UDF可以解决这个问题:

val removeRegexUDF = udf(
  (input: Seq[String]) => input.filterNot(s => s.matches("(https?\\://)\\S+"))
)

答案 1 :(得分:1)

是的,你可以。

首先,不是Array,而是类型应该是Seq或WrappedArray。 其次,函数只将一个字符串更改为其他字符串 - 而不是集合。

你的UDF应该是:

def removeRegex(input: Seq[String]) : Array[String]  = {
    input.map(x => regex.replaceAllIn(x, "")).toArray
}

因此,在每个元素上应用正则表达式。

您还可以使用Spark函数

中的函数regexp_replace