我是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的方式实现这一点?
答案 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)