Есть ли более Scala-esque способ ускорить эту функцию векторной обработки?
Я действительно новичок в Scala, и я пытался реализовать функцию, которая имеет два DenseVector Scala Breeze одинаковой длины. Оба вектора содержат двойные значения и 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?
2 ответа
Я только что посмотрел на Scaladoc на http://www.scalanlp.org/api/breeze/, но что-то вроде этого должно работать:
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)