我正在实现一些用于计算网页的PageRank的迭代算法,而我在找到存储内存中一些矩阵的最佳方法时遇到了一些麻烦。
我有一个B
n x n
矩阵,它显示了网页(B[i,j]=1/outdegree[j]
,如果有j
到i
,0
的弧线否则; outdegree[j]
是来自节点j
的传出弧的数量,并且我将其存储为scipy.sparse.dok_matrix
,因为它当然主要有0
个条目。问题是我必须计算Px
类型的许多矩阵x向量积,其中
P = B + (1/n)*e*d^T
其中e
是全1向量,d
是布尔向量,如果1
,则在j
组件中outdegree[j] > 0
。基本上e*d^T
是一种线性代数“技巧”来写n x n
矩阵,其中所有列都由1
s或0
s组成,具体取决于是否有相应的条目d
为1
或0
。
所以我正在努力解决两个问题,而不是完全独立的事情:
e*d.T
只是计算标量积,而我想要一个矩阵。我想这是一个聪明的广播和切片的使用,但我仍然是新的numpy,无法弄明白P
(假设我找到了1的解决方案),我放弃了将B
存储为稀疏矩阵的内存优势,突然间我需要存储n^2
浮动。无论如何,我添加到B
的矩阵非常冗余(只有两种类型的列),因此必须有一种比将整个矩阵存储在内存中更好的方法。有什么建议?请注意,它必须能够轻松地计算P.dot(x)
,x
任意向量答案 0 :(得分:2)
为简单起见,由于带有np.dot
的表达式会很庞大,让∙
表示矩阵乘法,e
,d
和x
是向量,即shape(n,1)和带方括号*
的表达式是python的列表multiplcation。然后,通过关联性
(e∙d.T)∙x = e∙(d.T∙x) = [[d.T∙x] * n]
其中d.T∙x
是标量,
P∙x = B∙x + 1/n * e∙d.T∙x = B∙x + 1/n * [[d.T∙x] * n]
因此,为了能够进行计算,您只能存储向量d。请注意,d.T∙x
(或者等效np.dot(d.T, x)
如果使用了数组)是向量积,并且是相对于矩阵乘法的廉价运算。
答案 1 :(得分:1)
第1点的答案是:
它从B
(M)数组和v1
(N)数组创建v2
(MxN)矩阵,使B(i,j) = v1[i]*v2[j]
2.答案更复杂。
B
,则只需将其定义为numpy.empty((n,n))
,将其填入问题的开头,然后B += (1/n)*np.outer(e, d)
n
不是太大,可能有稀疏或标准矩阵并没有太大差别np.outer(e, d)
视为稀疏矩阵,然后尝试this post