从空数组创建类型化数组列

时间:2016-12-02 09:46:11

标签: arrays apache-spark

我只想解决以下问题:我想过滤掉一个数据框的所有元组,其中一列中包含的字符串不包含在黑名单中,该黑名单是作为(可能为空)字符串数组给出的。

例如:如果黑名单包含“四十二”和“二十三”,则所有行都会从相应列包含“四十二”或“二十三”的数据帧中过滤掉。

如果blacklist不为空(例如Array(“fourty two”))并且else else(Array.empty [String]),则以下代码将成功执行:

//HELPERs
val containsStringUDF = udf(containsString(_: mutable.WrappedArray[String], _: String))
def containsString(array: mutable.WrappedArray[String], value: String) = {array.contains(value)}

def arrayCol[T](arr: Array[T]) = {array(arr map lit: _*)}

df.filter(!containsStringUDF(arrayCol[String](blacklist),$"theStringColumn"))

错误消息是:

org.apache.spark.sql.AnalysisException: cannot resolve 'UDF(array(), theStringColumn)' due to data type mismatch: argument 1 requires array<string> type, however, 'array()' is of array<null> type

看起来,空数组似乎无法点燃。有没有一个很好的方法来解决这个问题?

1 个答案:

答案 0 :(得分:2)

你正在思考一个问题。你真正需要的是isin

val blacklist = Seq("foo", "bar")

$"theStringColumn".isin(blacklist: _*)

此外,请勿依赖ArrayTypeWrappedArray的本地类型。只需使用Seq即可。

最后回答你的问题,你可以:

array().cast("array<string>")

或:

import org.apache.spark.sql.types.{ArrayType, StringType}

array().cast(ArrayType(StringType))