首先,我不是数学家。我承认这一点。然而,我仍然需要了解 ScyPy 的稀疏矩阵如何在算术上工作,以便在我必须处理的应用程序中从密集的 NumPy 矩阵切换到 SciPy 稀疏矩阵。问题是内存使用情况。大型密集矩阵将消耗大量内存。
有问题的公式部分是将矩阵添加到标量的位置。
A = V + x
其中 V 是一个方阵(它很大,比如 60,000 x 60,000)并且稀疏。 x 是一个 float 。
NumPy 的操作(如果我没记错的话)会将 x 添加到 V 中的每个字段。如果我完全偏离基础,请告诉我,并且 x 只会添加到 V 中的非零值。
对于 SciPy,并非所有稀疏矩阵都支持相同的功能,例如标量加法。 dok_matrix(键字典)支持标量加法,但看起来(在实践中)它分配每个矩阵条目,有效地将我的稀疏 dok_matrix 渲染为具有更多开销的密集矩阵。 (不好)
其他矩阵类型(CSR、CSC、LIL)不支持标量加法。
我可以尝试用标量值 x 构造一个完整矩阵,然后将其添加到 V。我对矩阵类型没有任何问题,因为它们似乎都支持矩阵加法。然而,我必须消耗大量内存才能将 x 构造为矩阵,并且加法的结果最终也可能是完全填充的矩阵。
必须有一种替代方法可以做到这一点,不需要分配 100% 的稀疏矩阵。
我愿意接受需要大量内存,但我想我应该先寻求一些建议。谢谢。
最佳答案
诚然,稀疏矩阵并不真正适合我,但 ISTM 的最佳前进方式取决于矩阵类型。如果您没问题:
>>> S = dok_matrix((5,5))
>>> S[2,3] = 10; S[4,1] = 20
>>> S.todense()
matrix([[ 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0.],
[ 0., 0., 0., 10., 0.],
[ 0., 0., 0., 0., 0.],
[ 0., 20., 0., 0., 0.]])
然后您可以更新:
>>> S.update(zip(S.keys(), np.array(S.values()) + 99))
>>> S
<5x5 sparse matrix of type '<type 'numpy.float64'>'
with 2 stored elements in Dictionary Of Keys format>
>>> S.todense()
matrix([[ 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0.],
[ 0., 0., 0., 109., 0.],
[ 0., 0., 0., 0., 0.],
[ 0., 119., 0., 0., 0.]])
性能不是特别好,但是 O(非零)。
OTOH,如果你有COO、CSC或CSR之类的东西,你可以直接修改data
属性:
>>> C = S.tocoo()
>>> C
<5x5 sparse matrix of type '<type 'numpy.float64'>'
with 2 stored elements in COOrdinate format>
>>> C.data
array([ 119., 109.])
>>> C.data += 1000
>>> C
<5x5 sparse matrix of type '<type 'numpy.float64'>'
with 2 stored elements in COOrdinate format>
>>> C.todense()
matrix([[ 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0.],
[ 0., 0., 0., 1109., 0.],
[ 0., 0., 0., 0., 0.],
[ 0., 1119., 0., 0., 0.]])
请注意,您可能想要添加额外的
>>> C.eliminate_zeros()
处理您添加了负数的可能性,因此现在实际记录的是 0
。就其本身而言,这应该可以正常工作,但是下一次当您执行C.data += some_number
技巧时,它会向其中添加somenumber
你介绍的零。
关于NumPy 矩阵到 SciPy 稀疏矩阵 : What is the safest way to add a scalar?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29303221/