Spark:输入一个向量

7
我正在学习Spark,但是在向量方面遇到了问题。 导入org.apache.spark.mllib.linalg.{Vectors, Vector}。
我的程序输入是一个包含RDD(Vector)输出的文本文件: dataset.txt:
[-0.5069793074881704,-2.368342680619545,-3.401324690974588]
[-0.7346396928543871,-2.3407983487917448,-2.793949129209909]
[-0.9174226561793709,-0.8027635530022152,-1.701699021443242]
[0.510736518683609,-2.7304268743276174,-2.418865539558031]

英译中:

所以,我尝试做的是:

val rdd = sc.textFile("/workingdirectory/dataset")
val data = rdd.map(s => Vectors.dense(s.split(',').map(_.toDouble)))

我出现了错误,因为它将[0.510736518683609视为数字。有没有直接加载存储在文本文件中的向量的方式,而不必执行第二行?我如何在map阶段删除“ [”?我在Spark中真的很新,请原谅如果这是一个非常明显的问题。
2个回答

4

在输入方面,您可以做的最简单的事情就是使用 Vectors.parse

scala> import org.apache.spark.mllib.linalg.Vectors
import org.apache.spark.mllib.linalg.Vectors

scala> Vectors.parse("[-0.50,-2.36,-3.40]")
res14: org.apache.spark.mllib.linalg.Vector = [-0.5,-2.36,-3.4]

它还可以与稀疏表示一起使用:
scala> Vectors.parse("(10,[1,5],[0.5,-1.0])")
res15: org.apache.spark.mllib.linalg.Vector = (10,[1,5],[0.5,-1.0])

将其与您的数据相结合,您需要的只有:
rdd.map(Vectors.parse)

如果您预期会出现格式不正确或空行的情况,您可以使用Try进行包装:
import scala.util.Try

rdd.map(line => Try(Vectors.parse(line))).filter(_.isSuccess).map(_.get)

1
我甚至不知道这个方法的存在!谢谢。 - eliasah

1
这是一种方法来实现它:

val rdd = sc.textFile("/workingdirectory/dataset")
val data = rdd.map {
   s => 
    val vect = s.replaceAll("\\[", "").replaceAll("\\]","").split(',').map(_.toDouble)
    Vectors.dense(vect)
}

我刚刚为了可读性将地图分成了行。
注意:记住,这只是对每行进行的简单字符串处理。

drop(1).dropRight(1).split(",").map(_.toDouble) 或者 val p = "-?[0-9]+(?:\\.[0-9]+)?".r; p.findAllIn(s).map(_.toDouble) 怎么样? - zero323
这就是为什么我说只有一种方式! :) - eliasah

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接