(0,1) - 矩阵与(0,1) - 向量的乘法

时间:2014-07-17 14:08:19

标签: python matrix binary

在Python中,我想将二进制矩阵(每个元素为0或1)与二进制向量相乘。矩阵的大小类似于100000 x 100,向量有100个元素。如果V和x分别是矩阵和向量(初始化为bool),这个简单的代码可以完成这项工作:

V.astype(np.int8).dot(x.astype(np.int8))

我的问题是:有没有办法通过利用2个操作数的二进制特性来更快地完成它?毕竟,100000次操作中的每一次都是V的一行与向量x之间的逻辑AND的总和。

感谢您的帮助。 帕特里克

编辑:刚试过你的解决方案unutbu。奇怪的是,2种方法(int8 et einsum)的性能在我的机器上似乎相似。

1 个答案:

答案 0 :(得分:1)

您可以使用np.einsum

In [12]: V = np.random.randint(2, size=(100000,100))
In [14]: x = np.random.randint(2, size=100)
In [15]: expected = V.astype(np.int8).dot(x.astype(np.int8))
In [28]: result = np.einsum('ij,j->i', V, x)

结果是一样的:

In [29]: np.allclose(expected, result)
Out[29]: True

np.einsum的速度提高了约3倍:

In [30]: %timeit np.einsum('ij,j->i', V, x)
100 loops, best of 3: 6.92 ms per loop
In [25]: %timeit V.astype(np.int8).dot(x.astype(np.int8))
10 loops, best of 3: 22.4 ms per loop

注意:与原始代码不同,np.einsum在这种情况下会返回一个dtype int32数组。


您可以尝试使用np.logical_andnp.sum,但这样做会慢得多:

In [45]: result2 = np.logical_and(V, x).sum(axis=1)

In [46]: np.allclose(expected, result2)
Out[46]: True

In [47]: %timeit np.logical_and(V, x).sum(axis=1)
10 loops, best of 3: 78 ms per loop

这可能会比较慢,因为分两步进行计算 需要形成中间阵列np.logical_and(V, x)的形状(100000,100)。调用np.einsum可让底层C ++函数直接计算结果。