"无需分配不必要数组的Numpy运算符结果总和"

2024-09-21 17:32:11 发布

您现在位置:Python中文网/ 问答频道 /正文

我有两个numpy布尔数组(ab)。我需要找出它们的元素有多少是相等的。目前,我做len(a) - (a ^ b).sum(),但据我所知,xor操作创建了一个全新的numpy数组。如何在不创建不必要的临时数组的情况下有效地实现这种期望的行为?在

我试过使用numexpr,但是我不能让它正常工作。它不支持True为1,False为0的概念,因此我必须使用ne.evaluate("sum(where(a==b, 1, 0))"),这大约需要两倍的时间。在

编辑:我忘记了,其中一个数组实际上是另一个大小不同的数组的视图,这两个数组都应该被认为是不可变的。两个数组都是二维的,大小都在25x40左右。在

是的,这是我程序的瓶颈,值得优化。在


Tags: numpyfalsetrue概念元素len时间情况
3条回答

在我的机器上这更快:

(a == b).sum()

如果你不想使用任何额外的存储空间,那么我建议使用numba。 我不太熟悉,但这似乎很管用。 我在让Cython使用布尔NumPy数组时遇到了一些麻烦。在

^{pr2}$

如果你没有numba,我建议使用@user2357112的答案

编辑:刚得到一个Cython版本,这是.pyx文件。我会同意的。在

from numpy cimport ndarray as ar
cimport numpy as np
cimport cython

@cython.boundscheck(False)
@cython.wraparound(False)
def cysumeq(ar[np.uint8_t,ndim=2,cast=True] a, ar[np.uint8_t,ndim=2,cast=True] b):
    cdef int i, j, h=a.shape[0], w=a.shape[1], tot=0
    for i in xrange(h):
        for j in xrange(w):
            if a[i,j] == b[i,j]:
                tot += 1
    return tot

首先,您可以跳过A*B步骤:

>>> a
array([ True, False,  True, False,  True], dtype=bool)
>>> b
array([False,  True,  True, False,  True], dtype=bool)
>>> np.sum(~(a^b))
3

如果你不介意摧毁阵法a或b,我不确定你会比这个更快:

^{pr2}$

如果问题是分配和取消分配,请维护一个输出数组,并告诉numpy每次都将结果放在那里:

out = np.empty_like(a) # Allocate this outside a loop and use it every iteration
num_eq = np.equal(a, b, out).sum()

但是,只有当输入总是相同的维度时,这才有效。如果你不需要一个大的数组大小,我可以保证每个部分的大小不一样。在

相关问题 更多 >