如何向量化这个矩阵运算?
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)
(我之前问过类似的问题,但这是不同的操作。)
我有 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)