是否有更多Scala式的方式来阻止这种矢量处理功能?

时间:2017-05-20 12:02:26

标签: scala vector scala-breeze

我是Scala的新手,我一直在尝试实现一个函数,它给出了两个长度相等的Scala Breeze DenseVectors。两个向量都包含双重值和NaN。该函数迭代两个向量并检查在当前索引处是否两个向量都具有double值。如果是这样,它会将相应的值附加到两个返回值向量。

即,给定向量v1 =(3.0,87.0,NaN,NaN,19.0)和v2 =(15.0,NaN,NaN,NaN,9.0),函数返回v1_new =(3.0,19.0),v2_new =(15.0, 9.0)。

我当前的实现似乎有效,看起来像这样:

def joint_space(vec_a : DenseVector[Double], vec_b : DenseVector[Double]) = {
  var a_placeholder = List[Double]()
  var b_placeholder = List[Double]()

  for (index <- 0 to vec_a.length-1) {
    if (!vec_a(index).isNaN && !vec_b(index).isNaN) {
      a_placeholder = a_placeholder :+ vec_a(index)
      b_placeholder = b_placeholder :+ vec_b(index)
    }
  }

  val joint_vec_a = DenseVector(a_placeholder:_*)
  val joint_vec_b = DenseVector(b_placeholder:_*)

  (joint_vec_a, joint_vec_b)
}

这对我来说似乎有点笨拙,我想知道如何以更加Scala-esque的方式实现这一点?

2 个答案:

答案 0 :(得分:2)

我只是在http://www.scalanlp.org/api/breeze/看了Scaladoc,但这样的事情应该有效:

val notNans = vec_a.mapValues(x => !x.isNaN) :&& vec_b.mapValues(x => !x.isNaN)
val indices = notNans.findAll(x => x)
(vec_a(indices), vec_b(indices))

或者更简单,val indices = (vec_a :+ vec_b).findAll(x => !x.isNaN)

答案 1 :(得分:1)

如果您不介意执行速度较慢,则可以使用zip / unzip作为单线解决方案:

scala> val v1 = List(3.0, 87.0, Double.NaN, Double.NaN, 19.0)
v1: List[Double] = List(3.0, 87.0, NaN, NaN, 19.0)

scala> val v2 = List(15.0, Double.NaN, Double.NaN, Double.NaN, 9.0)
v2: List[Double] = List(15.0, NaN, NaN, NaN, 9.0)

scala> val (o1, o2) = v1.zip(v2).filterNot { case (a, b) => (a * b).isNaN }.unzip
o1: List[Double] = List(3.0, 19.0)
o2: List[Double] = List(15.0, 9.0)