我有两列数据
arrayColumns1: org.apache.spark.sql.Column = array("col1","col2")
arrayColumns2: org.apache.spark.sql.Column = array("col1","col2")
两者似乎都是平等的,但它们来自不同的来源。
arrayColumns1
来自Array("col1","col2")
到array
的转化,使用此功能:
def asLitArray[T](xs: Seq[T]) = array(xs map lit: _*)
arrayColumns2
来自编写文本数组。
现在,当我尝试使用arrayColumns1
作为UDF函数的输入时:
.withColumn("udfFunction",udfFunction(arrayColumns))
其中
val udfFunction= udf(
{ xs : Seq[Double] =>
DO_SOMETHING
(output)
}
)
它让我觉得这个错误:
org.apache.spark.sql.AnalysisException: cannot resolve 'UDF(array(col1,col2))' due to data type mismatch: argument 1 requires array<double> type, however, 'array('col1','col2')' is of array<string> type.;;
但是当我使用arrayColumns2
时,它运行正常。我做错了什么?
我使用Spark 2.1而不是scala 2.11
答案 0 :(得分:0)
将文字数组传递给UDF没有多大意义,因为要传递的是列的名称,而不是文字值。您的第二种情况失败,因为您要创建字符串类型的列(lit("col1")
是一个内容为“col1”的文字列,它不引用列col1
)
我想这样:
def asColArray(xs: Seq[String]) = array((xs.map(x => col(x))): _*)
val arrayColumns = asColArray(Array("col1","col2"))
df.withColumn("udfFunction",udfFunction(arrayColumns))
如果你真的想使用文字值,你需要做这样的事情:
val arrayColumns = asLitArray(Array(1.0,2.0))
但是这会给你一个你的udf
的恒定输出