更改 BlockMatrix 的对角线元素

Changing the diagonal elements of BlockMatrix

我有一个大小为 4*4 的分块矩阵

Blockmatrix = 
    0.0  2.0  1.0  2.0
    2.0  0.0  2.0  4.0
    1.0  2.0  0.0  3.0
    2.0  4.0  3.0  0.0

在键入此矩阵的类型时,

正在显示

<class 'pyspark.mllib.linalg.distributed.BlockMatrix'>

我只想将对角线元素更改为 1.0

当我尝试这段代码时,

diagonal_matrix = DenseMatrix(dataframe_item.numRows,dataframe_item.numCols,dataframe_item.toLocalMatrix().rowIter().zipWithIndex().flatMap(lambda x:(x[1].toArray(x[2]),x[1].toArray())).toArray())

抛出以下错误,

AttributeError: 'DenseMatrix' object has no attribute 'rowIter'

谁能帮忙解决这个错误? 或者有没有更好的方法来更改 Pyspark 中 BlockMatrix 的对角线值?

试试这个,

from pyspark.mllib.linalg.distributed import *

rdd = sc.parallelize([
    (0, 0.0 , 2.0 , 1.0,  2.0),
    (1, 2.0 , 0.0 , 2.0 , 4.0),
    (2, 1.0 , 2.0 , 0.0 , 3.0),
    (3, 2.0 , 4.0  ,3.0  ,0.0)
    ])

Blockmatrix = IndexedRowMatrix(rdd.map(lambda x: IndexedRow(x[0],x[1:]))).toBlockMatrix()

这给了我们 Blockmatrix.

现在,要用 1.0 替换对角线元素,我们使用行索引。因此,我们将 BlockMatrix 转换为 IndexedRowMatrix,然后再转换为 rdd。因此我们有索引和行。

然后我们使用索引将所有对角线元素更改为 1.0,然后将其转换回 IndexedRowMatrix,然后再转换为 BlockMatrix

Blockmatrix_new = IndexedRowMatrix(Blockmatrix.toIndexedRowMatrix().rows\
                 .map(lambda x: IndexedRow(x.index, [1.0 if i == x.index else v for i,v in enumerate(x.vector)])))\
                 .toBlockMatrix()

Blockmatrix_new 是所需的矩阵。要查看内容,我们将其转换为本地矩阵。但请记住,这将导致矩阵被收集。

print Blockmatrix_new.toLocalMatrix()

DenseMatrix([[1., 2., 1., 2.],
             [2., 1., 2., 4.],
             [1., 2., 1., 3.],
             [2., 4., 3., 1.]])