Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/363.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 稀疏Scipy/Numpy:一种实现成对mins和运算的有效方法_Python_Numpy_Scipy_Sparse Matrix - Fatal编程技术网

Python 稀疏Scipy/Numpy:一种实现成对mins和运算的有效方法

Python 稀疏Scipy/Numpy:一种实现成对mins和运算的有效方法,python,numpy,scipy,sparse-matrix,Python,Numpy,Scipy,Sparse Matrix,在自然语言处理(NLP)中,计算向量之间的成对分钟之和非常流行,并用于计算相交直方图核[1]。然而,在NLP中,我们经常处理稀疏矩阵 下面是一种使用慢速for循环计算此操作的低效方法: import numpy as np from scipy.sparse import csr_matrix # Initialize sparse matrices A = csr_matrix(np.clip(np.random.randn(100, 64) - 1, 0, np.inf)) B = csr

在自然语言处理(NLP)中,计算向量之间的成对分钟之和非常流行,并用于计算相交直方图核[1]。然而,在NLP中,我们经常处理稀疏矩阵

下面是一种使用慢速for循环计算此操作的低效方法:

import numpy as np
from scipy.sparse import csr_matrix

# Initialize sparse matrices
A = csr_matrix(np.clip(np.random.randn(100, 64) - 1, 0, np.inf))
B = csr_matrix(np.clip(np.random.randn(64, 100) - 1, 0, np.inf))

# For each row, col vector i,j in A and B respectively
G = np.zeros((100, 100))
for i in range(A.shape[0]):
    for j in range(B.shape[1]):
        G[i, j] = A[i].minimum(B[:,j]).sum()
有没有一种方法可以在没有for循环的情况下实现这一点? 如果可以像使用
numba
中的
jit
那样编译for循环,我不会介意

此处给出了该方法的快速密集版本:

谢谢


[1]

这是一个应该非常高效的实现,尽可能地利用稀疏性。有一个环,但只有一个昏暗,所以应该不是太坏

import numpy as np
from scipy.sparse import csr_matrix, csc_matrix

M, N, K = 640, 100, 650

B1 = csr_matrix(np.clip(np.random.randn(N, K) - 1, 0, np.inf))
B2 = csr_matrix(np.clip(np.random.randn(N, K) - 1, 0, np.inf))
B = B1-B2
A1 = csc_matrix(np.clip(np.random.randn(M, N) - 1, 0, np.inf))
A2 = csc_matrix(np.clip(np.random.randn(M, N) - 1, 0, np.inf))
A = A1-A2

result = np.zeros((M, K))
for j in range(N):
    ia = A.indices[A.indptr[j] : A.indptr[j+1]]
    ib = B.indices[B.indptr[j] : B.indptr[j+1]]
    IA, IB = np.ix_(ia, ib)
    da = A.data[A.indptr[j] : A.indptr[j+1]]
    db = B.data[B.indptr[j] : B.indptr[j+1]]
    # both nonzero
    result[IA, IB] += np.minimum.outer(da, db)
    # one negative ...
    am = da<0
    iam, dam = ia[am], da[am]
    bm = db<0
    ibm, dbm = ib[bm], db[bm]
    # ... the other zero
    za = np.ones((M,), dtype=bool)
    za[ia] = False
    zb = np.ones((K,), dtype=bool)
    zb[ib] = False
    IA, IB = np.ix_(iam, zb)
    result[IA, IB] += dam[:, None]
    IA, IB = np.ix_(za, ibm)
    result[IA, IB] += dbm
# compare with dense method
print(np.allclose(result, np.minimum(A.A[..., None], B.A).sum(axis=1)))

至少在SciPy的最新版本中,有一个函数
SciPy.sparse.csr_matrix.minimum
,它在元素最小值方面与
numpy.minimum
等价。然而,我不知道计算效率有多高。

非零值总是正值吗?因此,它们不是真正稀疏的。为什么要使用稀疏表示?是内存效率问题困扰着你吗?@Divakar这只是为了举例说明,我使用的矩阵实际上非常稀疏。@hpaulj,非零值都是正值!那么,你的意思是它们是NumPy数组,但是非常“sparsey”,就像在许多零中一样?看起来很棒,我们来看看它是否使用
numba
@编译,好奇的很高兴听到它。顺便说一句,如果你的矩阵没有负数项,那么从
#一个负数…
到循环结束的代码就不需要了。你可以省略它。事实上,你应该这样做,因为那样会让事情变得更快。
True