假设我有一个RowMatrix.
我已将RowMatrix转换为DenseMatrix,如下所示
DenseMatrix Mat = new DenseMatrix(m,n,MatArr);
Run Code Online (Sandbox Code Playgroud)
这需要将RowMatrix转换为JavaRDD并将JavaRDD转换为数组.
有没有其他方便的方法来进行转换?
提前致谢
ars*_*ars 17
如果有人感兴趣,我已经实现了@javadba提出的分布式版本.
def transposeRowMatrix(m: RowMatrix): RowMatrix = {
val transposedRowsRDD = m.rows.zipWithIndex.map{case (row, rowIndex) => rowToTransposedTriplet(row, rowIndex)}
.flatMap(x => x) // now we have triplets (newRowIndex, (newColIndex, value))
.groupByKey
.sortByKey().map(_._2) // sort rows and remove row indexes
.map(buildRow) // restore order of elements in each row and remove column indexes
new RowMatrix(transposedRowsRDD)
}
def rowToTransposedTriplet(row: Vector, rowIndex: Long): Array[(Long, (Long, Double))] = {
val indexedRow = row.toArray.zipWithIndex
indexedRow.map{case (value, colIndex) => (colIndex.toLong, (rowIndex, value))}
}
def buildRow(rowWithIndexes: Iterable[(Long, Double)]): Vector = {
val resArr = new Array[Double](rowWithIndexes.size)
rowWithIndexes.foreach{case (index, value) =>
resArr(index.toInt) = value
}
Vectors.dense(resArr)
}
Run Code Online (Sandbox Code Playgroud)
您可以使用BlockMatrix,它可以从IndexedRowMatrix创建:
BlockMatrix matA = (new IndexedRowMatrix(...).toBlockMatrix().cache();
matA.validate();
BlockMatrix matB = matA.transpose();
Run Code Online (Sandbox Code Playgroud)
然后,可以轻松地将其作为IndexedRowMatrix.这在spark文档中有描述.
您是对的:没有
RowMatrix.transpose()
Run Code Online (Sandbox Code Playgroud)
方法。您将需要手动执行此操作。
这是非分布式/本地矩阵版本:
def transpose(m: Array[Array[Double]]): Array[Array[Double]] = {
(for {
c <- m(0).indices
} yield m.map(_(c)) ).toArray
}
Run Code Online (Sandbox Code Playgroud)
在分布式版本将大致如下:
origMatRdd.rows.zipWithIndex.map{ case (rvect, i) =>
rvect.zipWithIndex.map{ case (ax, j) => ((j,(i,ax))
}.groupByKey
.sortBy{ case (i, ax) => i }
.foldByKey(new DenseVector(origMatRdd.numRows())) { case (dv, (ix,ax)) =>
dv(ix) = ax
}
Run Code Online (Sandbox Code Playgroud)
警告:我没有测试上面的:这将有错误。但是基本方法是有效的-类似于我过去为小型SparkLinAlg库所做的工作。
归档时间: |
|
查看次数: |
7182 次 |
最近记录: |