从 Spark 中的字符串列表创建文字和列数组 SQL

Create array of literals and columns from List of Strings in Spark SQL

我正在尝试在 Scala 中定义将字符串列表作为输入的函数,并将它们转换为传递给下面代码中使用的数据帧数组参数的列。

val df = sc.parallelize(Array((1,1),(2,2),(3,3))).toDF("foo","bar")
val df2 = df
        .withColumn("columnArray",array(df("foo").cast("String"),df("bar").cast("String")))
        .withColumn("litArray",array(lit("foo"),lit("bar")))

更具体地说,我想创建函数 colFunctionlitFunction(或者如果可能的话只创建一个函数),它们将字符串列表作为输入参数,并且可以按如下方式使用:

val df = sc.parallelize(Array((1,1),(2,2),(3,3))).toDF("foo","bar")
val colString = List("foo","bar")
val df2 = df
         .withColumn("columnArray",array(colFunction(colString))
         .withColumn("litArray",array(litFunction(colString)))

我已经尝试将 colString 映射到包含所有转换的列数组,但这不起作用。关于如何实现这一目标的任何想法?非常感谢阅读问题,以及任何 suggestions/solutions.

Spark 2.2+:

SeqMapTuple (struct) 文字的支持已添加到 SPARK-19254. According to tests:

import org.apache.spark.sql.functions.typedLit

typedLit(Seq("foo", "bar"))

Spark < 2.2

只需 maplit 并用 array 换行:

def asLitArray[T](xs: Seq[T]) = array(xs map lit: _*)

df.withColumn("an_array", asLitArray(colString)).show
// +---+---+----------+
// |foo|bar|  an_array|
// +---+---+----------+
// |  1|  1|[foo, bar]|
// |  2|  2|[foo, bar]|
// |  3|  3|[foo, bar]|
// +---+---+----------+

关于从 Seq[String] 到类型 ArrayColumn 的转换,此功能已由以下人员提供:

def array(colName: String, colNames: String*): Column 

def array(cols: Column*): Column

示例:

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

cols match { case x::xs => df.select(array(x, xs:_*)) 
// or 
df.select(array(cols map col: _*))

当然,所有列都必须是同一类型。