Есть ли более 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)
Другие вопросы по тегам