我正在尝试转换以下代码段
public org.apache.spark.mllib.linalg.Vector call(Tuple2<IntWritable, VectorWritable> arg0)
throws Exception {
org.apache.mahout.math.Vector mahoutVector = arg0._2.get();
Iterator<Element> elements = mahoutVector.nonZeroes().iterator();
ArrayList<Tuple2<Integer, Double>> tupleList = new ArrayList<Tuple2<Integer, Double>>();
while (elements.hasNext()) {
Element e = elements.next();
if (e.index() >= nCols || e.get() == 0)
continue;
Tuple2<Integer, Double> tuple = new Tuple2<Integer, Double>(e.index(), e.get());
tupleList.add(tuple);
}
org.apache.spark.mllib.linalg.Vector sparkVector = Vectors.sparse(nCols, tupleList);
return sparkVector;
}
我对scala相当新,所以我不知道如何正确转换它。到目前为止,我得到了
def transformSvec(x: Vector) : org.apache.spark.mllib.linalg.Vector = {
val iter=x.nonZeroes.iterator()
//iterate the items and add to an arraylist
//or an iterable/seq for scala, if var seq: Seq[(Int, scala.Double)] is chosen then
org.apache.spark.mllib.linalg.Vectors.sparse(x.size, seq)
}
有人可以帮忙吗?提前谢谢。
答案 0 :(得分:3)
Tuple来自Scala,而不是Java。在Scala中,您可以使用正确的语法,但(IntWritable, VectorWriteable)
是类型Tuple2[IntWriteable, VectorWriteable]
的特殊语法
您还可以使用此语法实例化元组。你的java代码
Tuple2<Integer, Double> tuple = new Tuple2<Integer, Double>(e.index(), e.get());
成为
val tuple = (e.index(), e.get())
如果您愿意,可以使用Scala中的ArrayList,没有什么可以阻止您,但它通常更喜欢使用Scala集合,因为它们具有更多功能,可以更好地与Scala的其余部分一起使用。 scala.collection.mutable.ArrayBuffer
是与java.util.ArrayList
等效的Scala。
但是,在Scala中,将事物添加到循环中的集合中并不像在Java中那样常见。通常,您将使用不可变集合和方法(如map
,flatmap
和filter
)来转换和生成新集合。在您的情况下,您可以使用
val tupleList = x.nonZeroes.iterator()
.filter(e => e.index < ncols)
.filter(e => e.get != 0)
.map(e => (e.index(), e.get))
.toSeq
生成序列。
答案 1 :(得分:1)
在Mahout 0.13.0中,您还可以使用MahoutCollections
import org.apache.mahout.math.scalabindings.MahoutCollections._
val a = Array(1.0, 2.0, 3.0)
val v: Vector = new org.apache.mahout.math.DenseVector(a)
v.toArray
您可以将数组传递给Spark Vector的构造函数