使用Scala在Spark中将数组转换为自定义字符串格式

时间:2018-07-24 07:48:41

标签: scala apache-spark apache-spark-sql user-defined-functions

我创建了一个$,如下所示:

DataFrame

然后我尝试将import spark.implicits._ import org.apache.spark.sql.functions._ val df = Seq( (1, List(1,2,3)), (1, List(5,7,9)), (2, List(4,5,6)), (2, List(7,8,9)), (2, List(10,11,12)) ).toDF("id", "list") val df1 = df.groupBy("id").agg(collect_set($"list").as("col1")) df1.show(false) 行值转换为字符串,如下所示:

WrappedArray

我真正想要的是生成如下输出:

import org.apache.spark.sql.functions._
def arrayToString = udf((arr: collection.mutable.WrappedArray[collection.mutable.WrappedArray[String]]) => arr.flatten.mkString(", "))

val d = df1.withColumn("col1", arrayToString($"col1"))
d: org.apache.spark.sql.DataFrame = [id: int, col1: string]

scala> d.show(false)
+---+----------------------------+
|id |col1                        |
+---+----------------------------+
|1  |1, 2, 3, 5, 7, 9            |
|2  |4, 5, 6, 7, 8, 9, 10, 11, 12|
+---+----------------------------+

我该如何实现?

1 个答案:

答案 0 :(得分:4)

您不需要udf函数,简单的concat_ws应该可以解决您的问题

import org.apache.spark.sql.functions._
val df1 = df.withColumn("list", concat_ws("$", col("list")))
            .groupBy("id")
            .agg(concat_ws(", ", collect_set($"list")).as("col1"))

df1.show(false)

应该给您

+---+----------------------+
|id |col1                  |
+---+----------------------+
|1  |1$2$3, 5$7$9          |
|2  |7$8$9, 4$5$6, 10$11$12|
+---+----------------------+

通常,应避免使用udf函数如果内置函数可用,因为 udf函数需要将列数据序列化和反序列化为原始类型以进行计算并分别从基元到列

更加简洁,您可以避免

withColumn步骤
val df1 = df.groupBy("id")
            .agg(concat_ws(", ", collect_set(concat_ws("$", col("list")))).as("col1"))

我希望答案会有所帮助