如何向量化这个矩阵运算?

How to Vectorize This Matrix Operation?

(我之前问过类似的问题,但这是不同的操作。)

我有 2 个布尔掩码数组,我希望计算两个掩码的每个组合的操作。

慢版

N = 10000
M = 580
masksA = np.array(np.random.randint(0,2, size=(N,M)), dtype=np.bool)
masksB = np.array(np.random.randint(0,2, size=(N,M)), dtype=np.bool)

result = np.zeros(shape=(N,N), dtype=np.float)
for i in range(N):
    for j in range(N):
        result[i,j] = np.float64(np.count_nonzero(np.logical_and(masksA[i,:],masksB[j,:]))) / M

第一个输入似乎是 masksA,因为问题文本显示为 - "operation on every combination of two masks"

我们可以用matrix-multiplication来解决,像这样-

result = masksA.astype(np.float).dot(masksB.T)/M

或者,使用较低的精度 np.float32 进行 dtype 转换以加快计算速度。因为我们是在计数,精度低一点应该没问题。

计时 -

In [5]: N = 10000
   ...: M = 580
   ...: 
   ...: np.random.seed(0)
   ...: masksA = np.array(np.random.randint(0,2, size=(N,M)), dtype=np.bool)
   ...: masksB = np.array(np.random.randint(0,2, size=(N,M)), dtype=np.bool)

In [6]: %timeit masksA.astype(np.float).dot(masksB.T)
1.87 s ± 50.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [7]: %timeit masksA.astype(np.float32).dot(masksB.T)
1 s ± 7.93 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)