我的问题如下。我有两个形状为n,p的数组X
和Y
,其中 p >> n (例如n = 50,p = 10000)。
相对于mask
,我也有一个{strong>小密度的遮罩p
(大小为p
的布尔数的一维数组)(例如{ {1}}是0.05)。
我尝试相对于np.mean(mask)
尽可能快地计算X
和Y
的内积:输出mask
是形状为{的数组{1}},并且这样inner
。
我尝试使用n, n
库,但是使用起来很慢:
inner[i, j] = np.sum(X[i, np.logical_not(mask)] * Y[j, np.logical_not(mask)])
但是,在我的机器上,numpy.ma
比import numpy as np
import numpy.ma as ma
n, p = 50, 10000
density = 0.05
mask = np.array(np.random.binomial(1, density, size=p), dtype=np.bool_)
mask_big = np.ones(n)[:, None] * mask[None, :]
X = np.random.randn(n, p)
Y = np.random.randn(n, p)
X_ma = ma.array(X, mask=mask_big)
Y_ma = ma.array(Y, mask=mask_big)
慢5倍...
首先,我认为这是一个问题,X_ma.dot(Y_ma.T)
不知道掩码仅针对X.dot(Y.T)
,但是我无法使用此信息。
我正在寻找一种执行计算的方法,并且不会比幼稚的点慢很多。
非常感谢!
答案 0 :(得分:2)
我们可以使用matrix-multiplication
带有和不带有蒙版的版本,因为从完整版的蒙版减法会为我们提供所需的输出-
inner = X.dot(Y.T)-X[:,mask].dot(Y[:,mask].T)
或者简单地使用反光罩,虽然对于mask
来说很慢-
inner = X[:,~mask].dot(Y[:,~mask].T)
时间-
In [34]: np.random.seed(0)
...: p,n = 10000,50
...: X = np.random.rand(n,p)
...: Y = np.random.rand(n,p)
...: mask = np.random.rand(p)>0.95
In [35]: mask.mean()
Out[35]: 0.0507
In [36]: %timeit X.dot(Y.T)-X[:,mask].dot(Y[:,mask].T)
100 loops, best of 3: 2.54 ms per loop
In [37]: %timeit X[:,~mask].dot(Y[:,~mask].T)
100 loops, best of 3: 4.1 ms per loop
In [39]: %%timeit
...: inner = np.empty((n,n))
...: for i in range(X.shape[0]):
...: for j in range(X.shape[0]):
...: inner[i, j] = np.sum(X[i, ~mask] * Y[j, ~mask])
1 loop, best of 3: 302 ms per loop