我是Spark的新手。 我正在尝试读取具有以下数据的文本文件:
时间戳ID计数器值
00:01 1 c1 0.5 00:02 5 c3 0.3 00:03 1 c2 0.1 00:04 2 c2 0.13
并将它们转换为:
(id,array_of_counters):
(1, [ c1 c2 ]) [ 0.5 0.1]
因此,对于每个id
,我创建一个2d array
,它将包含文本文件中特定id
的每个计数器和每个值。
我尝试用Vectors
来做,但我认为存储在它们中的内容必须是双倍的,我不能添加两个向量,除非它们是微风矢量。
然后,我发现有一个名为Vector
的数据结构,但我找不到任何有关它的细节。
所以,我的问题是Vector
中Vectors
和mllib
之间的主要区别是什么?
代码:
val inputRdd = sc.textFile(inputFile).map(x => x.split(","))
val data = inputRdd.map(y => (y(1), Vector(y(2), y(3)))).reduceByKey(_++_)
答案 0 :(得分:0)
我不认为Vector
对于你在这里尝试做什么是必要或适当的(我可能是错的,我们需要更多关于你想要完成的细节)。唯一有意义的方法是,每个id都有固定数量的计数器(c1
,c2
等...)。如果你只是想要一组每个id,以及它的计数器和值的相应列表,试试这个(我假设计数器对每个id
是唯一的) :
val data = inputRdd
.map(y => (y(1).toLong, y(2), y(3).toDouble))
.toDF("id", "counter", "value")
.groupBy("id")
.agg(collect_list(map($"counter", $"value")))
.as[(Long, Seq[Map[String, Double]])]
.map(r => (r._1, r._2.reduce(_++_)))
//this results in a Dataset[(Long, Map[String, Double])]
火花ml.linalg.Vector
基本上是Array[Double]
,并且每条记录都需要固定数量的counter
。您可以通过data
对其Map[String, Double]
进行排序,然后从._1
创建Vector
.values
,从上面的Vector
转换为向量}}
ml.linalg.Vectors
只是一个辅助对象,其中包含用于创建mllib
个对象的函数。
org.apache.spark.ml.linalg.Vector的工厂方法。我们不使用名称Vector,因为Scala默认导入scala.collection.immutable.Vector。
值得注意的是,ml
适用于较旧的RDD API,而RDD[(Long, Seq[(String, Double)])]
适用于较新的Dataframe / Dataset API。
val data = inputRdd
.map(y => (y(1).toLong, Seq[(String, Double)]((y(2), y(3).toDouble))))
.reduceByKey(_++_)
Select * from table t where exist
(Select 1 from
(Select user, max(date) as date from table) A
Where A.user = t.user and A.date = t.date )