【问题标题】:Fast inner product of two 2-d masked arrays in numpynumpy中两个二维掩码数组的快速内积
【发布时间】:2019-01-21 16:57:52
【问题描述】:

我的问题如下。我有两个数组 XY,形状为 n,p 其中 p >> n(例如 n = 50,p = 10000)。

相对于p,我还有一个掩码mask(大小为p 的布尔值的一维数组),密度为small(例如np.mean(mask) 为0.05)。

我尝试尽可能快地计算XY 相对于mask 的内积:输出inner 是一个形状为n, n 的数组,并且是这样的@ 987654332@.

我曾尝试使用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)

但是,在我的机器上,X_ma.dot(Y_ma.T)X.dot(Y.T) 慢大约 5 倍...

首先,我认为.dot 不知道掩码仅针对p 是一个问题,但我不知道是否可以使用此信息。

我正在寻找一种方法来执行计算而不会比天真的点慢很多。

非常感谢!

【问题讨论】:

  • 对于常规数值数组 np.dot 使用快速编译的 BLAS(或类似)库。我不知道它对掩码数组的作用的细节,至少它必须做一个额外的dot 来处理掩码。我知道在object dtype 数组的情况下,它会使用对象的 * 和 + 方法。
  • scipy.sparse 可能是这里的方式 - 你可以将你的 X 和 Y 转换为稀疏矩阵,然后从那里开始
  • 在演示中,您只屏蔽了 5% 的术语。

标签: python numpy


【解决方案1】:

我们可以使用 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-11-01
    • 2022-01-26
    • 1970-01-01
    • 2011-09-07
    • 1970-01-01
    • 2021-08-14
    • 1970-01-01
    • 2021-11-12
    相关资源
    最近更新 更多