创建一个新的累加器和向量加法

时间:2015-12-05 00:32:53

标签: scala apache-spark

我正在关注Spark Programming Guide但遇到accumulatorVector

的一些问题

我有以下对象定义VectorAccumulatorParam

object VectorAccumulatorParam extends AccumulatorParam[Vector] {
    def zeros(initialValue: Vector): Vector = {
        Vectors.zeros( initialValue.size )
    }
    def addInPlace(v1: Vector, v2: Vector): Vector = {
        v1 += v2
    }
}

使用方式如下:

import org.apache.spark.SparkContext
import org.apache.spark.SparkContext._
import org.apache.spark.SparkConf
import org.apache.spark.rdd.RDD
import org.apache.spark.AccumulatorParam
import org.apache.spark.mllib.linalg.{Vector, Vectors}

object SimpleSpark {
    def main(arg: Array[String]) = {
        /* some coed */

        val valAccum = sc.accumulator( Vector(1, 2, 3) )(VectorAccumulatorParam) 

        /* some coed */
}

但我有两个错误:

[error] /home/cliu/Documents/github/Apache-Spark/src/main/scala/SimpleSpark.scala:125: type mismatch;
[error]  found   : VectorAccumulatorParam.type
[error]  required: org.apache.spark.AccumulatorParam[scala.collection.immutable.Vector[Int]]
[error]         val valAccum = sc.accumulator( Vector(1, 2, 3) )(VectorAccumulatorParam) 
[error]                                                          ^
[error] /home/cliu/Documents/github/Apache-Spark/src/main/scala/SimpleSpark.scala:170: value += is not a member of org.apache.spark.mllib.linalg.Vector
[error]         v1 += v2
[error]            ^

第一:为什么存在类型不匹配?这是编程指南中的内容。它应该返回Vector

第二:如果操作v1 += v2不起作用,为什么指南是这样的?

2 个答案:

答案 0 :(得分:3)

  1. 您收到类型错误,因为Vector(1, 2, 3)创建了scala.collection.immutable.Vector,这是Array的不可变等价物,而不是mllib.linalg.Vectormllib.linalg.Vectors不提供随播广告对象

  2. 正如Alberto Bonsanto mllib.linalg.Vectors所述,不支持添加操作。

  3. 参数定义中也存在拼写错误。方法的正确名称为zero而非zeros

  4. 关于编程指南,我猜您错过了以下声明:

      

    假设我们有一个表示数学向量的Vector类,我们可以写

  5. 您可以使用breeze.linalg.Vector创建累加器:

    import breeze.linalg.{DenseVector => BDV}
    
    object VectorAccumulatorParam extends AccumulatorParam[BDV[Double]] {
      def zero(v: BDV[Double]): BDV[Double] = v
      def addInPlace(v1: BDV[Double], v2: BDV[Double]): BDV[Double] = v1 += v2
    }
    
    val valAccum = sc.accumulator(BDV.zeros[Double](3))(VectorAccumulatorParam) 
    

    另请参阅:Difference between spark Vectors and scala immutable Vector?

答案 1 :(得分:1)

第二个是第一个,因为它更容易。 如果您阅读Vector的文档,您将意识到他们没有+=方法,因此您想要实现的连接不能以这种方式完成,但是其他一些类支持该方法,看看Accumulator,所以我的建议是编写自己的方法来实现这一目标。