spark scala:将DataFrame OR Dataset转换为单个逗号分隔的字符串

时间:2018-02-20 19:08:58

标签: java scala apache-spark spark-dataframe

下面是spark scala代码,它将打印一列DataSet [Row]:

import org.apache.spark.sql.{Dataset, Row, SparkSession}
val spark: SparkSession = SparkSession.builder()
        .appName("Spark DataValidation")
        .config("SPARK_MAJOR_VERSION", "2").enableHiveSupport()
        .getOrCreate()

val kafkaPath:String="hdfs:///landing/APPLICATION/*"
val targetPath:String="hdfs://datacompare/3"
val pk:String = "APPLICATION_ID" 
val pkValues = spark
        .read
        .json(kafkaPath)
        .select("message.data.*")
        .select(pk)
        .distinct() 
pkValues.show()

关于代码的输出:

+--------------+
|APPLICATION_ID|
+--------------+
|           388|
|           447|
|           346|
|           861|
|           361|
|           557|
|           482|
|           518|
|           432|
|           422|
|           533|
|           733|
|           472|
|           457|
|           387|
|           394|
|           786|
|           458|
+--------------+

问题:

如何将此数据帧转换为逗号分隔的String变量?

预期输出:

val   data:String= "388,447,346,861,361,557,482,518,432,422,533,733,472,457,387,394,786,458"

请建议如何将DataFrame [Row]或Dataset转换为一个String。

2 个答案:

答案 0 :(得分:3)

我认为这不是一个好主意,因为dataFrame是一个分布式对象并且可以是无关紧要的。 Collect会将所有数据带到驱动程序中,因此您应该仔细执行此类操作。

以下是使用dataFrame(两个选项)可以执行的操作:

df.select("APPLICATION_ID").rdd.map(r => r(0)).collect.mkString(",")
df.select("APPLICATION_ID").collect.mkString(",")

测试数据框只有3行的结果:

String = 388,447,346

编辑:使用DataSet,您可以直接执行:

ds.collect.mkString(",")

答案 1 :(得分:0)

使用collect_list:

import org.apache.spark.sql.functions._
val data = pkValues.select(collect_list(col(pk))) // collect to one row
    .as[Array[Long]] // set encoder, so you will have strongly-typed Dataset
    .take(1)(0) // get the first row - result will be Array[Long]
    .mkString(",") // and join all values

然而,执行收集或占用所有行是一个非常糟糕的主意。相反,您可能希望使用.write将pkValues保存在某处?或者将其作为其他函数的参数,以保持分布式计算

编辑:刚刚注意到,@SCouto在我之后发布了其他答案。收集也是正确的,使用collect_list函数你有一个好处 - 如果你愿意,你可以轻松地进行分组,即将键组分为偶数和奇数组。这取决于你喜欢哪种解决方案,更简单的收集或更长的一行,但更强大