Spark Scala:拆分多个RDD之间的每一行

时间:2016-09-17 01:25:06

标签: scala apache-spark rdd

我在HDFS上有一个文件:

61,139,75
63,140,77
64,129,82
68,128,56
71,140,47
73,141,38
75,128,59
64,129,61
64,129,80
64,129,99

我从中创建了一个RDD并用它们的索引压缩元素:

val data = sc.textFile("hdfs://localhost:54310/usrp/sample.txt")
val points = data.map(s => Vectors.dense(s.split(',').map(_.toDouble)))
val indexed = points.zipWithIndex()
val indexedData = indexed.map{case (value,index) => (index,value)}

现在我需要使用索引和每行的前两个元素创建rdd1。然后需要使用每行的索引和第三个元素创建rdd2。我是Scala的新手,你能帮我解决一下这个问题吗?

这不起作用,因为y不是Vector类型,而是org.apache.spark.mllib.linalg.Vector

val rdd1 = indexedData.map{case (x,y) => (x,y.take(2))}

基本上如何获得这样一个向量的前两个元素?

感谢。

2 个答案:

答案 0 :(得分:1)

您可以按照以下步骤实现上述输出:

原始数据:

http://www.example.com/iPython/spawn

RRD1数据:

将索引与每行的前两个元素一起使用。

indexedData.foreach(println)
(0,[61.0,139.0,75.0])
(1,[63.0,140.0,77.0])
(2,[64.0,129.0,82.0])
(3,[68.0,128.0,56.0])
(4,[71.0,140.0,47.0])
(5,[73.0,141.0,38.0])
(6,[75.0,128.0,59.0])
(7,[64.0,129.0,61.0])
(8,[64.0,129.0,80.0])
(9,[64.0,129.0,99.0])

RRD2数据:

将索引与行的第三个元素一起使用。

val rdd1 = indexedData.map{case (x,y) => (x, (y.toArray(0), y.toArray(1)))}
rdd1.foreach(println)
(0,(61.0,139.0))
(1,(63.0,140.0))
(2,(64.0,129.0))
(3,(68.0,128.0))
(4,(71.0,140.0))
(5,(73.0,141.0))
(6,(75.0,128.0))
(7,(64.0,129.0))
(8,(64.0,129.0))
(9,(64.0,129.0))

答案 1 :(得分:1)

您可以使用DenseVector的{​​{1}}方法在模式匹配中获取基础unapply,然后调用Array[Double] / take在数组上,用Vector:

重新包装它
drop

正如您所看到的 - 这意味着您创建的原始val rdd1 = indexedData.map { case (i, DenseVector(arr)) => (i, Vectors.dense(arr.take(2))) } val rdd2 = indexedData.map { case (i, DenseVector(arr)) => (i, Vectors.dense(arr.drop(2))) } 实际上并不那么有用,因此如果您不打算在其他地方使用DenseVector,那么创建{可能更好{1}}首先是indexedData

indexedData

最后提示:您可能希望在RDD[(Long, Array[Double])]上调用val points = data.map(s => s.split(',').map(_.toDouble)) val indexedData: RDD[(Long, Array[Double])] = points.zipWithIndex().map(_.swap) val rdd1 = indexedData.mapValues(arr => Vectors.dense(arr.take(2))) val rdd2 = indexedData.mapValues(arr => Vectors.dense(arr.drop(2))) ,然后再扫描两次以创建.cache()indexedData - 否则文件将被加载并解析两次。