我正在尝试在 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")))
更具体地说,我想创建函数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)))
我尝试将colString
映射到具有所有转换的列数组,但这不起作用。
Spark 2.2+:
SPARK-19254 中添加了对Seq
、Map
和Tuple
(struct
(文本的支持。根据测试:
import org.apache.spark.sql.functions.typedLit
typedLit(Seq("foo", "bar"))
火花<2.2
只需用lit
map
并用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]
到Array
类型的Column
的转换,此功能已由以下人员提供:
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: _*))
当然,所有列必须属于同一类型。
要创建包含数组类型列的 df(3 种备选方案(:
val df = Seq(
(Seq("foo", "bar")),
(Seq("baz", "qux")),
).toDF("col_name")
val df = Seq(
(Array("foo", "bar")),
(Array("baz", "qux")),
).toDF("col_name")
val df = Seq(
(List("foo", "bar")),
(List("baz", "qux")),
).toDF("col_name")
要添加数组类型的列:
提供现有的 col 名称
df.withColumn("new_col", array("col1", "col2"))
提供现有 col 名称的列表
df.withColumn("new_col", array(list_of_str map col: _*))
提供文本值(2 个备选方案(
df.withColumn("new_col", typedLit(Seq("foo", "bar"))) df.withColumn("new_col", array(lit("foo"), lit("bar")))
提供文本值列表(2 个备选方案(
df.withColumn("new_col", typedLit(list_of_str)) df.withColumn("new_col", array(list_of_str map lit: _*))