有没有一种更像 Scala 式的方法来推动这个矢量处理函数


我对Scala

真的很陌生,我一直在尝试实现一个函数,该函数被赋予两个长度相等的Scala Breeze DenseVectors。两个向量都包含双精度值和 NaN。该函数遍历两个向量,并检查在当前索引处,两个向量是否具有双精度值。如果是这样,它将各自的值附加到两个返回值向量。

即,给定向量 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 式的方式实现这一点?

我只是在 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).

如果您不介意较慢的实现速度,则可以将 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)

最新更新