首先,我不是数学家。我承认。然而,我仍然需要理解ScyPy的稀疏矩阵是如何算术运算的,以便在我必须处理的应用程序中从密集的NumPy矩阵切换到SciPy稀疏矩阵。问题是内存使用情况。一个大的密集矩阵将消耗大量的内存。
问题的公式部分是将矩阵添加到标量的位置。
A = V + x
其中V是一个方形矩阵(它的大,例如60,000 x 60,000)并且人口稀少。 x是一个浮点数。
使用NumPy的操作(如果我没有弄错的话)将v添加到V中的每个字段。如果我完全偏离基础,请告诉我,x只会添加到非零V中的值。
使用SciPy,并非所有稀疏矩阵都支持相同的功能,例如标量添加。 dok_matrix(Keys of Keys)支持标量添加,但看起来(实际上)它分配每个矩阵条目,有效地将我的稀疏dok_matrix渲染为具有更多开销的密集矩阵。 (不好)
其他矩阵类型(CSR,CSC,LIL)不支持标量添加。
我可以尝试构建一个标量值为x的完整矩阵,然后将其添加到V.我对矩阵类型没有任何问题,因为它们似乎都支持矩阵加法。但是我不得不耗费大量的内存来构造x作为矩阵,并且添加的结果也可能最终成为完全填充的矩阵。
必须有另一种方法来做到这一点,并不需要分配100%的稀疏矩阵。
我会接受需要大量的记忆,但我想我会首先寻求一些建议。感谢。
答案 0 :(得分:5)
不可否认,稀疏矩阵并不是我的驾驶室,但ISTM最好的前进方式取决于矩阵类型。如果你是DOK:
>>> 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
添加到你引入的零点。