Как найти среднее значение тех же ячеек в массиве матриц Бриза в искровых скалах? - PullRequest
0 голосов
/ 27 июня 2018

У меня есть 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|
  +----+----+

Это не СДР, так как я хочу, чтобы этот код работал на драйвере.

Spark Scala является новым для меня, и все, что я могу думать, это что-то вроде:

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

Но я не знаю, правильно ли это, так как кажется, что это closure. Кроме того, он ожидает тип возврата DenseMatrix[Double], но я получаю ошибку, потому что, если СДР пуст, у меня его нет. Есть идеи?

Ответы [ 2 ]

0 голосов
/ 28 июня 2018

При использовании бриз-матриц вы можете использовать + для поэлементного сложения двух разных матриц. Это означает, что единственное, что вам нужно сделать, это сложить все матрицы вместе, а затем разделить на количество матриц. Это можно сделать следующим образом:

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)
0 голосов
/ 28 июня 2018

вы можете использовать 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()
...