python-3.x - 高效的稀疏矩阵列变化
问题描述
我正在实现一个高效的 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 矩阵非常非常大,这种方法根本无法扩展。我怎样才能有效地做到这一点?
解决方案
如果不重新分配和复制基础数据结构,就无法添加新的非零值。如果您希望这些零列非常常见(> 25% 的数据),您应该以其他方式处理它们,或者您最好使用密集数组。
否则试试这个:
import scipy.sparse
M = scipy.sparse.rand(1000, 1000, density=0.001, format='csr')
nz_col_weights = scipy.sparse.csr_matrix(M.shape, dtype=M.dtype)
nz_col_weights[:, M.getnnz(axis=0) == 0] = 1 / (M.shape[0] - 1)
nz_col_weights.setdiag(0)
M += nz_col_weights
这只有两个分配操作
推荐阅读
- javascript - 为什么我的程序会超出 gmail api 的拉取配额?
- c# - 通过 C#、Exchange 和 EWS 托管 API 发送电子邮件会出现错误 407:请求失败 - 需要代理身份验证。为什么?
- python - 如何使用 python 在 ID3v2 mp3 文件上添加 SYLT(同步歌词)标签?
- java - 在复杂的不可变对象中初始化集合
- pyspark - 过滤pySpark数据框中的日期列记录
- javascript - 如何使用 OnClick 事件设置 Jquery Mobile 导航
- java - Mockito.verify 不适用于 Lombok @Delegate
- linux - PHP 是使用我的操作系统的“语言环境”还是它自己内置的 ICU 语言环境数据?
- r - 在 R 中改变数据框以添加带有 if 条件的列时出错
- android - 在退出线程之前将最后一个任务安全地发布到 Handler