我有一个大小为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的对角线值?
答案 0 :(得分:0)
尝试一下
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.]])