Python SciPy稀疏矩阵上的numpy.allclose()

Python SciPy稀疏矩阵上的numpy.allclose(),python,numpy,scipy,sparse-matrix,Python,Numpy,Scipy,Sparse Matrix,我使用的是稀疏矩阵,但是numpy.allclose()函数给出了错误,因为它只接受numpy数组作为输入。我不想将稀疏矩阵转换为数组,然后再转换回稀疏矩阵,因为这样效率会很低。是否有其他方法检查两个稀疏矩阵的allclose()?您可以设置用于比较的体系结构,然后使用numpy进行评估: def simrank_sparse(A,c,maxiter,eps=1e-4): if not sp.issparse(A): raise Exception("Input is

我使用的是稀疏矩阵,但是
numpy.allclose()
函数给出了错误,因为它只接受numpy数组作为输入。我不想将稀疏矩阵转换为数组,然后再转换回稀疏矩阵,因为这样效率会很低。是否有其他方法检查两个稀疏矩阵的
allclose()

您可以设置用于比较的体系结构,然后使用numpy进行评估:

def simrank_sparse(A,c,maxiter,eps=1e-4):

    if not sp.issparse(A):
        raise Exception("Input is not a sparse matrix ")

    n=sp.csr_matrix.get_shape(A)[0]
    Q=misc.get_column_normalized_matrix(A)
    sim=sp.eye(n)
    I=sp.eye(n)
    sim_prev=sp.csr_matrix(sim)

    for t in range(maxiter):

        if sc.allclose(sim,sim_prev,atol=eps):
            break
        sim_prev=sc.copy(sim)
        sim=c*(Q.T*sim_prev*Q)+(1-c)*I

    print("Converge after %d iterations (eps=%f)." % (t, eps))
    return sim
def csr\u allclose(a、b、rtol=1e-5、atol=1e-8):
c=np.abs(np.abs(a-b)-rtol*np.abs(b))

返回c.max()如果您知道矩阵在稀疏性(非零数量和匹配的非零索引)中匹配,那么您可以只比较
数据

def csr_allclose(a, b, rtol=1e-5, atol = 1e-8):
    c = np.abs(np.abs(a - b) - rtol * np.abs(b))
    return c.max() <= atol
如果矩阵是以相同的方式构造的,或者其中一个矩阵是另一个矩阵的保稀疏导数,则该结果为真

一些时间测试:

np.allclose(sim.data,sim_prev.data,atol=eps)
如果矩阵稀疏匹配,我们可以比较
数据
属性以节省大量时间:

In [155]: M1 = sparse.random(1000,1000,.2, 'csr')
In [156]: 
In [156]: timeit np.abs(M-M1).max()
12.3 ms ± 339 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [157]: timeit np.abs(M.A-M1.A).max()
24.4 ms ± 624 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
对稀疏性进行初步检查可以节省大量时间(前提是我们不担心ε
size非零值):

从计时中删除
toarray()
步骤,在同等大小的密集阵列上有效地执行
allclose

In [170]: timeit np.allclose(M.indptr,M1.indptr)
97.8 µs ± 2.29 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
稀疏矩阵的减法比我预期的要好


实际上我不需要使用
np.abs
;Python
abs
委托给
M.\uuu abs\uuuu
方法,即:

In [164]: %%timeit Ma=M.A; M1a=M1.A
     ...: np.abs(Ma-M1a).max()
     ...: 
14.8 ms ± 31 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

通常,
numpy
函数不适用于
sparse
矩阵。也有例外,通常是因为函数将操作委托给矩阵方法。我想不起稀疏的等价物,但检查文档。要从头开始,我首先比较
shape
dtype
nnz
。然后比较
sim.indptr
属性。这是整数,我想应该是
allclose
。从那里,我们必须比较
索引
,然后比较
数据
属性。但我们可能需要首先检查它们是否是“cannonical”——所有的零都已删除,重复项已求和,列也已按顺序排列。有很多东西要检查。@Warren:谢谢你能抓到。更新以解决错误。
In [170]: timeit np.allclose(M.indptr,M1.indptr)
97.8 µs ± 2.29 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
In [164]: %%timeit Ma=M.A; M1a=M1.A
     ...: np.abs(Ma-M1a).max()
     ...: 
14.8 ms ± 31 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
def __abs__(self):
    return self._with_data(abs(self._deduped_data()))