你可以使用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_and 和np.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
这可能会更慢,因为分两步进行计算
需要形成一个形状为 (100000, 100) 的中间数组np.logical_and(V, x)。调用 np.einsum 让底层 C++ 函数直接计算结果。