如何在Breeze中向SparseVector的每个元素添加一个?

时间:2018-09-25 22:18:41

标签: scala scala-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来获取Array [Double]的日志,但这并不多。我担心在具有大型SparseVectors的分布式应用程序中,这会很慢。

1 个答案:

答案 0 :(得分:0)

火花1.6.3

您可以定义一些UDF在Spark中进行任意矢量化加法。首先,您需要设置将Spark向量转换为Breeze向量的功能;这样做的一个例子是here。进行隐式转换后,您将有一些选择。

要添加任何两列,您可以使用:

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)))
  }
} 

请注意,上面链接的问题中确定了对asBreezefromBreeze(以及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矢量参数中将此名称设为通用。