【发布时间】:2020-05-22 05:09:42
【问题描述】:
我正在实施一种高效的 PageRank 算法,因此我使用的是稀疏矩阵。我很接近,但有一个问题。我有一个矩阵,我希望每列的总和为一。这很容易实现,但是当我得到一个零列的矩阵时就会出现问题。
在这种情况下,我想将列中的每个元素设置为 1/(n-1),其中 n 是矩阵的维度。我除以 n-1 而不是 n,因为我希望始终保持对角线为零。
我怎样才能有效地实现这一点?我天真的解决方案是只确定每列的总和,然后找到为零的列索引并用 1/(n-1) 值替换整个列,如下所示:
# naive approach (too slow!)
# M is my nxn sparse matrix where each column sums to one
col_sums = M.sum(axis=0)
for i in range(n):
if col_sums[0,i] == 0:
# set entire column to 1/(n-1)
M[:, i] = 1/(n-1)
# make sure diagonal is zeroed
M[i,i] = 0
我的 M 矩阵非常非常非常大,这种方法根本无法扩展。我怎样才能有效地做到这一点?
【问题讨论】:
-
使用
csc格式的矩阵可能比csr更好。或进行转置(因此您正在处理行),并可能在设置行时转换为lil格式。另一个想法是尝试一次设置所有0列,至少设置1/n-1值。添加非零值是最昂贵的步骤,因为它会改变稀疏性。简单地扩展现有的非零值相对便宜。 -
尝试一次性设置值,比如用 cols = np.where(col_sums==0)[0] 计算零列,然后像 M[:,cols] = 1/ 那样进行赋值(n-1)。然后进行另一轮作业,将所有对角线都归零。您也许可以使用 M[np.arange(n),np.arange(n)] 或 np.diag_indices(n) 访问对角线。
标签: python-3.x algorithm numpy scipy sparse-matrix