一种方法是首先使用sets 识别a 和b 共有的所有不同元素。如果a 和b 中的值没有太多不同的可能性,这应该可以很好地工作。然后只需要遍历不同的值(在变量values 下方)并使用np.argwhere 来识别这些值出现的a 和b 中的索引。然后可以使用np.repeat 和np.tile 构造稀疏矩阵的二维索引:
import numpy as np
from scipy import sparse
a = np.random.randint(0, 10, size=(400,))
b = np.random.randint(0, 10, size=(300,))
## matrix generation after OP
I1 = sparse.csr_matrix((a[:,None]==b),shape=(len(a),len(b)))
##identifying all values that occur both in a and b:
values = set(np.unique(a)) & set(np.unique(b))
##here we collect the indices in a and b where the respective values are the same:
rows, cols = [], []
##looping over the common values, finding their indices in a and b, and
##generating the 2D indices of the sparse matrix with np.repeat and np.tile
for value in values:
x = np.argwhere(a==value).ravel()
y = np.argwhere(b==value).ravel()
rows.append(np.repeat(x, len(x)))
cols.append(np.tile(y, len(y)))
##concatenating the indices for different values and generating a 1D vector
##of True values for final matrix generation
rows = np.hstack(rows)
cols = np.hstack(cols)
data = np.ones(len(rows),dtype=bool)
##generating sparse matrix
I3 = sparse.csr_matrix( (data,(rows,cols)), shape=(len(a),len(b)) )
##checking that the matrix was generated correctly:
print((I1 != I3).nnz==0)
生成csr矩阵的语法取自documentation。稀疏矩阵相等的测试取自this post。
旧答案:
我不知道性能,但至少您可以通过使用简单的生成器表达式来避免构造完整的密集矩阵。这里有一些代码使用两个 1d 随机整数数组首先按照 OP 发布的方式生成稀疏矩阵,然后使用生成器表达式测试所有元素的相等性:
import numpy as np
from scipy import sparse
a = np.random.randint(0, 10, size=(400,))
b = np.random.randint(0, 10, size=(300,))
## matrix generation after OP
I1 = sparse.csr_matrix((a[:,None]==b),shape=(len(a),len(b)))
## matrix generation using generator
data, rows, cols = zip(
*((True, i, j) for i,A in enumerate(a) for j,B in enumerate(b) if A==B)
)
I2 = sparse.csr_matrix((data, (rows, cols)), shape=(len(a), len(b)))
##testing that matrices are equal
## from https://stackoverflow.com/a/30685839/2454357
print((I1 != I2).nnz==0) ## --> True
我认为没有办法绕过双循环,理想情况下这将被推入numpy,但至少对于生成器,循环进行了一些优化......