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

Ben*_*Kok 8 arrays scala apache-spark apache-spark-sql

我试图在Scala中定义函数,将函数列表作为输入,并将它们转换为传递给下面代码中使用的dataframe数组参数的列.

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")))
Run Code Online (Sandbox Code Playgroud)

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

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)))
Run Code Online (Sandbox Code Playgroud)

我已经尝试将colString映射到具有所有转换的列数组,但这不起作用.关于如何实现这一点的任何想法?非常感谢您阅读该问题以及任何建议/解决方案.

zer*_*323 22

Spark 2.2+:

支持Seq,MapTuple(struct)的文字已被添加SPARK-19254.根据测试:

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

typedLit(Seq("foo", "bar"))
Run Code Online (Sandbox Code Playgroud)

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]|
// +---+---+----------+
Run Code Online (Sandbox Code Playgroud)

关于转型,从Seq[String]Column类型的Array这一功能已经提供:

def array(colName: String, colNames: String*): Column 
Run Code Online (Sandbox Code Playgroud)

要么

def array(cols: Column*): Column
Run Code Online (Sandbox Code Playgroud)

例:

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

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

当然,所有列必须属于同一类型.