如何将双打数组数组转换为RDD [String]

时间:2017-03-24 15:00:24

标签: scala apache-spark rdd

我需要将Array[Array[Double]]转换为RDD,例如[[1.1, 1.2 ...], [2.1, 2.2 ...], [3.1, 3.2 ...], ...]转换为

+-----+-----+-----+ | 1.1 | 1.2 | ... | | 2.1 | 2.2 | ... | | 3.1 | 3.2 | ... | | ... | ... | ... | +-----+-----+-----+

val testDensities: Array[Array[Double]] = Array(Array(1.1, 1.2), Array(2.1, 2.2), Array(3.1, 3.2))
val testData = spark.sparkContext
  .parallelize(Seq(testDensities
    .map { x => x.toArray }
      .map { x => x.toString() } ))

这段代码甚至感觉不正确,第二个map调用应该映射数组中的每个元素以将Double转换为String。这是我将其保存为文本文件时得到的结果。

[Ljava.lang.String;@773d7a60

任何人都可以评论我该怎么办,以及我在哪里犯了一个可怕的错误?

感谢。

2 个答案:

答案 0 :(得分:4)

如果要将Array [Double]转换为String,可以使用mkString方法将数组的每个项目与分隔符连接起来(在我的示例中为","

scala> val testDensities: Array[Array[Double]] = Array(Array(1.1, 1.2), Array(2.1, 2.2), Array(3.1, 3.2))
scala> val rdd = spark.sparkContext.parallelize(testDensities)
scala> val rddStr = rdd.map(_.mkString(","))

rddStr: org.apache.spark.rdd.RDD[String] = MapPartitionsRDD[7] at map at 

scala> rddStr.collect.foreach(println)
1.1,1.2
2.1,2.2
3.1,3.2

答案 1 :(得分:1)

也许是这样的:

scala> val testDensities: Array[Array[Double]] = Array(Array(1.1, 1.2), Array(2.1, 2.2), Array(3.1, 3.2))
scala> val strRdd = sc.parallelize(testDensities).map(_.mkString("[",",","]"))
strRdd: org.apache.spark.rdd.RDD[String] = MapPartitionsRDD[16] at map at <console>:26
scala> strRdd.collect
res7: Array[String] = Array([1.1,1.2], [2.1,2.2], [3.1,3.2])

但我有两个问题:

  • 你为什么要这样做?我明白这只是因为你是 学习,你正在玩Spark。
  • 为什么要尝试使用&#34;数组&#34;?这不是我第一次看到人们尝试转换所有数组。 将RDD保留到最后并使用更多通用集合类型。

为什么你的代码错了: 因为您在本地数组中应用了映射(在驱动程序中),然后从列表列表中创建RDD。 所以:

  • 您没有并行执行地图。事实上,你没有任何并行化。
  • 您创建列表的RDD而不是字符串。

如果您在控制台中执行代码:

scala> val testData = sc.parallelize(Seq(testDensities.map { x => x.toArray }.map { x => x.toString() } ))
testData: org.apache.spark.rdd.RDD[Array[String]] = ParallelCollectionRDD[14] at parallelize at <console>:26

回复很明确:RDD[Array[String]]