应该如何处理这个混合 scipy.sparse / numpy 程序

How this mixed scipy.sparse / numpy program should be handled

我目前正在尝试使用 numpy 以及 scipy 来处理稀疏矩阵,但是,在评估矩阵的稀疏性的过程中,我遇到了麻烦,我不知道如何应理解以下行为:

import numpy as np
import scipy.sparse as sp

a=sp.csc.csc_matrix(np.ones((3,3)))
a
np.count_nonzero(a)

使用上面的代码计算 a 和非零计数时,我在 ipython 中看到了这个输出:

Out[9]: <3x3 sparse matrix of type '' with 9 stored elements in Compressed Sparse Column format>

Out[10]: 1

我觉得这里有些地方我不明白。 一个全为 1 的 3*3 矩阵,应该有 9 个非零项,这就是我使用 scipy 中的 toarray 方法得到的答案。 我可能以错误的方式使用了 numpy 和 scipy ?

非零计数可用作属性:

In [295]: a=sparse.csr_matrix(np.arange(9).reshape(3,3))
In [296]: a
Out[296]: 
<3x3 sparse matrix of type '<class 'numpy.int32'>'
    with 8 stored elements in Compressed Sparse Row format>
In [297]: a.nnz
Out[297]: 8

正如 Warren 评论的那样,您不能指望 numpy 函数在 sparse 上运行。使用 sparse 函数和方法。有时 numpy 函数是以调用数组自己的方法的方式编写的,在这种情况下函数调用可能会起作用。但这仅在具体情况下才是正确的。

Ipython 中,我大量使用 a.<tab> 来获取完成列表(属性和方法)。我也是用function??看代码的

np.count_nonzero 的情况下,我看不到任何代码 - 它已编译,并且仅适用于 np.ndarray 个对象。

np.nonzero(a) 有效。查看它的代码,发现它在寻找数组的方法:nonzero = a.nonzero

稀疏非零方法代码为:

def nonzero(self):
    ...
    # convert to COOrdinate format
    A = self.tocoo()
    nz_mask = A.data != 0
    return (A.row[nz_mask],A.col[nz_mask])

A.data !=0 行之所以存在,是因为可以构造一个包含 0 个数据元素的矩阵,特别是如果您使用 coo (data,(i,j)) 格式。因此,除了谨慎之外,nnz 属性提供了可靠的计数。

a.<tab> 我还看到了 a.getnnza.eleminate_zeros 方法,如果您担心偷偷摸摸的零,这可能会有所帮助。

有时直接使用稀疏矩阵的数据属性很有用。访问它们比修改它们更安全。但是每种稀疏格式都有不同的属性。在 csr 的情况下你可以这样做:

In [306]: np.count_nonzero(a.data)
Out[306]: 8