我在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))}
基本上如何获得这样一个向量的前两个元素?
感谢。
答案 0 :(得分:1)
您可以按照以下步骤实现上述输出:
http://www.example.com/iPython/spawn
将索引与每行的前两个元素一起使用。
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])
将索引与行的第三个元素一起使用。
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
- 否则文件将被加载并解析两次。