稀疏矩阵中的高效访问

时间:2016-07-26 14:12:01

标签: python numpy matrix scipy sparse-matrix

我正在使用推荐系统,但我正在努力处理scipy稀疏矩阵的访问时间。

在这种情况下,我正在实现 TrustSVD ,因此我需要一个有效的结构来操作列和行(CSR,CSC)。我已经考虑过使用两种结构,字典......但无论哪种方式,这总是太慢,特别是与numpy矩阵运算相比。

for u, j in zip(*ratings.nonzero()):
    items_rated_by_u = ratings[u, :].nonzero()[1]
    users_who_rated_j = ratings[:, j].nonzero()[0]
    # More code...

附加: 每个循环大约需要0.033秒,因此迭代一次通过35,000次评级意味着每次迭代等待19分钟(SGD)并且至少25次迭代我们谈论的是8小时。此外,这里我只是谈论访问,如果我包括分解部分,则需要大约2天。

1 个答案:

答案 0 :(得分:2)

当您索引稀疏矩阵时,特别是只需要一个行或列,它不仅需要选择值,还必须构造一个新的稀疏矩阵。 np.ndarray构造是在编译代码中完成的,但大多数稀疏构造都是纯Python。 nonzero()[1]构造要求将矩阵转换为coo格式并选择rowcol属性(查看其代码)。

我认为您可以通过查看rows格式的lil属性或其转置来更快地访问您的行列:

In [418]: sparse.lil_matrix(np.matrix('0,1,0;1,0,0;0,1,1'))
Out[418]: 
<3x3 sparse matrix of type '<class 'numpy.int32'>'
    with 4 stored elements in LInked List format>
In [419]: M=sparse.lil_matrix(np.matrix('0,1,0;1,0,0;0,1,1'))
In [420]: M.A
Out[420]: 
array([[0, 1, 0],
       [1, 0, 0],
       [0, 1, 1]], dtype=int32)
In [421]: M.rows
Out[421]: array([[1], [0], [1, 2]], dtype=object)
In [422]: M[1,:].nonzero()[1]
Out[422]: array([0], dtype=int32)
In [423]: M[2,:].nonzero()[1]
Out[423]: array([1, 2], dtype=int32)
In [424]: M.T.rows
Out[424]: array([[1], [0, 2], [2]], dtype=object)

你也可以csr格式访问这些值,但它有点复杂

In [425]: M.tocsr().indices
Out[425]: array([1, 0, 1, 2], dtype=int32)