如何在Spark Scala中找到一系列Breeze矩阵中相同单元的均值?

时间:2018-06-27 18:44:39

标签: scala apache-spark matrix mean scala-breeze

我有一个Array[DenseMatrix[Double]],我想找到相同单元格的均值。例如:

Array[0]: 
  +---+---+
  | 1 | 2 |
  +---+---+ 
  | 2 | 3 |
  +---+---+

Array[1]: 
  +---+---+
  | 1 | 1 |
  +---+---+ 
  | 3 | 1 |
  +---+---+

Array[2]:
  +---+---+
  | 2 | 3 |
  +---+---+ 
  | 4 | 1 |
  +---+---+

Result: DenseMatrix: 
  +----+----+
  | 1.3|  2 |
  +----+----+ 
  |  3 | 1.6|
  +----+----+

这不是RDD,因为我希望此代码在驱动程序上运行。

Spark Scala对我来说是陌生的,我所能想到的只是:

  val ar = rdd.collect().foreach(x=> {
    val matr = DenseMatrix.zeros[Double](C,2)
    matr := x/M
    matr
  })

但是我不知道它是否正确,因为它认为它是closure。另外,它期望返回DenseMatrix[Double]的类型,但是我得到了错误,因为如果RDD为空,我就没有。有什么想法吗?

2 个答案:

答案 0 :(得分:1)

使用微风矩阵时,可以使用+对两个不同的矩阵进行逐元素加法。这意味着您唯一需要做的就是将所有矩阵加在一起,然后除以矩阵数。可以完成以下操作:

import breeze.linalg.DenseMatrix

val arr = Array(new DenseMatrix(2, 2, Array(1.0,2,2,3)), 
        new DenseMatrix(2, 2, Array(1.0,3,1,1)),
        new DenseMatrix(2, 2, Array(2.0,4,3,1)))

val dm: DenseMatrix = arr.reduce(_ + _).map(_ / arr.length)

结果矩阵将具有相同单元格的均值。


在使用 Spark ml.linalg.DenseMatrix 矩阵时,这也是可能的,但是,由于没有简单的加法,所以它有点复杂。

val numCols = arr.head.numCols
val numRows = arr.head.numRows
val values = arr.map(_.values)
  .reduce((_, _).zipped.map(_ + _))
  .map(_ / arr.length)

val dm = new DenseMatrix(numCols, numRows, values)

答案 1 :(得分:0)

您可以像这样使用fold

val rdd    = sc.makeRDD(Seq(1, 2, 3))
val zero   = 0
val sum    = rdd.fold(zero)((l, r) => l + r) // = (((0 + 1) + 2) + 3)
val result = sum / rdd.count()