我在Scala中有一个CoordinateMatrix格式的矩阵。矩阵是稀疏的,而且整体看起来像(在coo_matrix.entries.collect上),
Array[org.apache.spark.mllib.linalg.distributed.MatrixEntry] = Array(
MatrixEntry(0,0,-1.0), MatrixEntry(0,1,-1.0), MatrixEntry(1,0,-1.0),
MatrixEntry(1,1,-1.0), MatrixEntry(1,2,-1.0), MatrixEntry(2,1,-1.0),
MatrixEntry(2,2,-1.0), MatrixEntry(0,3,-1.0), MatrixEntry(0,4,-1.0),
MatrixEntry(0,5,-1.0), MatrixEntry(3,0,-1.0), MatrixEntry(4,0,-1.0),
MatrixEntry(3,3,-1.0), MatrixEntry(3,4,-1.0), MatrixEntry(4,3,-1.0),
MatrixEntry(4,4,-1.0))
这只是一个小样本。矩阵的大小为N×N(其中N = 1百万),尽管其中大部分是稀疏的。在Spark Scala中获取此矩阵的行总和的有效方法之一是什么?目标是创建一个由行和组成的新RDD,即大小为N,其中第一个元素是row1的行和,依此类推。
我总是可以将此coordinateMatrix转换为IndexedRowMatrix并运行for循环,一次一次迭代计算rowums,但这不是最有效的方法。
非常感谢任何想法。
答案 0 :(得分:2)
由于改组(这是你在这里无法避免的部分),这将是相当昂贵的,但你可以将条目转换为PairRDD
并按键减少:
import org.apache.spark.mllib.linalg.distributed.{MatrixEntry, CoordinateMatrix}
import org.apache.spark.rdd.RDD
val mat: CoordinateMatrix = ???
val rowSums: RDD[Long, Double)] = mat.entries
.map{case MatrixEntry(row, _, value) => (row, value)}
.reduceByKey(_ + _)
与基于indexedRowMatrix
的解决方案不同:
import org.apache.spark.mllib.linalg.distributed.IndexedRow
mat.toIndexedRowMatrix.rows.map{
case IndexedRow(i, values) => (i, values.toArray.sum)
}
它不需要groupBy
转换或中间SparseVectors
。