在对numpy.ndarray
求和时,它会降低数组的维数,除非我们设置keepdims=True
。然而,对于Scipy的稀疏矩阵来说,这似乎并非如此:
import scipy.sparse
matrix = scipy.sparse.coo_matrix([[0, 1], [2, 1]])
print(matrix.shape) # (2, 2) as expected.
print(matrix.sum().shape) # () as expected.
print(matrix.sum(axis=0).shape) # (1, 2) but expected (2,).
print(matrix.sum(axis=0)[0].shape) # (1, 2) but expected (2,).
如示例中的最后一行所示,我甚至无法选择结果向量。此外,尝试将总和的结果转换为密集的Numpy数组失败:
matrix.toarray() # This works.
matrix.sum(axis=0).toarray() # AttributeError: 'matrix' has no 'toarray'.
如何计算沿一维的稀疏矩阵之和并将结果作为密集数组获得?
答案 0 :(得分:2)
稀疏矩阵,而不同的类(取决于格式的类)尝试表现得像np.matrix
(其行为类似于旧式的MATLAB矩阵)。它的形状总是2d,索引,求和和相关动作返回2d。
In [172]: M = sparse.csr_matrix([[0,1],[2,1]])
In [173]: M
Out[173]:
<2x2 sparse matrix of type '<class 'numpy.int32'>'
with 3 stored elements in Compressed Sparse Row format>
总和产生标量或0d数组:
In [174]: M.sum()
Out[174]: 4
In [175]: _.shape
Out[175]: ()
In [176]: type(__)
Out[176]: numpy.int32
轴总和产生2d列或行向量密集矩阵:
In [177]: M.sum(axis=0)
Out[177]: matrix([[2, 2]], dtype=int32)
In [178]: _.shape
Out[178]: (1, 2)
In [179]: M.sum(axis=1)
Out[179]:
matrix([[1],
[3]])
In [180]: _.shape
Out[180]: (2, 1)
这与从密集矩阵获得的行为相同,例如M.todense()
。 keepdims=True
为数组提供类似的东西(来自MATLAB的人抱怨sum
缩小了维度。)
密集矩阵具有方便的.A1
属性,可将其转换为1d数组:
In [181]: M.sum(axis=1).A1
Out[181]: array([1, 3])
In [182]: M.sum(axis=0).A1
Out[182]: array([2, 2], dtype=int32)
.A
适用于稀疏矩阵和密集矩阵,但只有稀疏有toarray
方法(和todense
)。就像我说的那样,稀疏模仿密集矩阵,但不是一个子类。
稀疏轴和实际上进行矩阵乘法;密集矩阵*稀疏矩阵产生密集矩阵:
In [186]: M*np.matrix([[1],[1]])
Out[186]:
matrix([[1],
[3]], dtype=int32)
In [187]: np.matrix([[1,1]])*M
Out[187]: matrix([[2, 2]], dtype=int32)
关于阵列总和的投诉不要离开这个&#39;空的&#39; (单数是一个术语,1不是0)维度:
Why does the shape remains same when I sum a square numpy array along either directions?