Как добавить один к каждому элементу SparseVector в Breeze? - PullRequest
0 голосов
/ 26 сентября 2018

Для объекта Breeze SparseVector:

scala>  val sv = new SparseVector[Double](Array(0, 4, 5), Array(1.5, 3.6, 0.4), 8)
sv: breeze.linalg.SparseVector[Double] = SparseVector(8)((0,1.5), (4,3.6), (5,0.4))

Как лучше всего вести журнал значений + 1?

Вот один из способов, который работает:

scala>  new SparseVector(sv.index, log(sv.data.map(_ + 1)), sv.length)
res11: breeze.linalg.SparseVector[Double] = SparseVector(8)((0,0.9162907318741551), (4,1.5260563034950492), (5,0.3364722366212129))

Мне это не нравится, потому что он не использует бриз для добавления.Мы используем легкий UFunc, чтобы взять журнал массива [Double], но это немного.Я обеспокоен тем, что в распределенном приложении с большими SparseVectors это будет медленно.

1 Ответ

0 голосов
/ 09 марта 2019

Spark 1.6.3

Вы можете определить некоторые пользовательские функции для произвольного векторизованного сложения в Spark.Во-первых, вам нужно настроить возможность преобразования векторов Spark в векторы Breeze;пример этого - здесь .Как только у вас есть неявные преобразования, у вас есть несколько вариантов.

Чтобы добавить любые два столбца, вы можете использовать:

def addVectors(v1Col: String, v2Col: String, outputCol: String): DataFrame => DataFrame = {
      // Error checking column names here
  df: DataFrame => {
    def add(v1: SparkVector, v2: SparkVector): SparkVector =
      (v1.asBreeze + v2.asBreeze).fromBreeze
    val func = udf((v1: SparkVector, v2: SparkVector) => add(v1, v2))
    df.withColumn(outputCol, func(col(v1Col), col(v2Col)))
  }
} 

Обратите внимание, использование asBreeze и fromBreeze (а также псевдоним для SparkVector) установлено ввопрос, связанный выше.Возможное решение - сделать буквенный целочисленный столбец с помощью

df.withColumn(colName, lit(1))

, а затем добавить столбцы.

Альтернатива для более сложных математических функций:

def applyMath(func: BreezeVector[Double] => BreezeVector[Double], 
                 inColName: String, outColName: String): DataFrame => DataFrame = {
  df: DataFrame => df.withColumn(outColName, 
    udf((v1: SparkVector) => func(v1.asBreeze).fromBreeze).apply(col(inColName)))
}

Вы также можете сделать это универсальным в параметре вектора Breeze.

...