比较两个numpy数组的最快方法

3

我有两个数组:

>>> import numpy as np
>>> a=np.array([2, 1, 3, 3, 3])
>>> b=np.array([1, 2, 3, 3, 3])

如何最快地比较这两个数组的元素是否相等,而不考虑顺序?

编辑 我测量了以下函数的执行时间:

def compare1():        #works only for arrays without redundant elements
    a=np.array([1,2,3,5,4])
    b=np.array([2,1,3,4,5])
    temp=0
    for i in a:
        temp+=len(np.where(b==i)[0])
    if temp==5:
            val=True
    else:
            val=False
    return 0

def compare2():
    a=np.array([1,2,3,3,3])
    b=np.array([2,1,3,3,3])
    val=np.all(np.sort(a)==np.sort(b))
    return 0

def compare3():                        #thx to ODiogoSilva
    a=np.array([1,2,3,3,3])
    b=np.array([2,1,3,3,3])
    val=set(a)==set(b)
    return 0

import numpy.lib.arraysetops as aso
def compare4():                        #thx to tom10
    a=np.array([1,2,3,3,3])
    b=np.array([2,1,3,3,3])
    val=len(aso.setdiff1d(a,b))==0
    return 0

结果如下:
>>> import timeit
>>> timeit.timeit(compare1,number=1000)
0.0166780948638916
>>> timeit.timeit(compare2,number=1000)
0.016178131103515625
>>> timeit.timeit(compare3,number=1000)
0.008063077926635742
>>> timeit.timeit(compare4,number=1000)
0.03257489204406738

看起来 ODiogoSilva 的 "set" 方法是最快的。

你知道还有其他我可以测试的方法吗?

编辑2 上面的运行时间并不适合用来比较数组,正如 user2357112 在评论中所解释的那样。

#test.py
import numpy as np
import numpy.lib.arraysetops as aso

#without duplicates
N=10000
a=np.arange(N,0,step=-2)
b=np.arange(N,0,step=-2)

def compare1():
    temp=0
    for i in a:
        temp+=len(np.where(b==i)[0])
    if temp==len(a):
        val=True
    else:
        val=False
    return val
def compare2():
    val=np.all(np.sort(a)==np.sort(b))
    return val
def compare3():
    val=set(a)==set(b)
    return val
def compare4():
    val=len(aso.setdiff1d(a,b))==0
    return val

输出结果如下:
>>> from test import *
>>> import timeit
>>> timeit.timeit(compare1,number=1000)
101.16708397865295
>>> timeit.timeit(compare2,number=1000)
0.09285593032836914
>>> timeit.timeit(compare3,number=1000)
1.425955057144165
>>> timeit.timeit(compare4,number=1000)
0.44780397415161133

现在compare2是最快的。还有什么方法能够超越它吗?


你只是想知道它们是否具有相同的元素吗?在这种情况下是1、2、3吗? - ODiogoSilva
1
排序两个,然后只需比较我猜测。 - Baum mit Augen
@ODiogoSilva 是的,我的第一次尝试只是为了查看这些数组是否包含1、2、3。 - Andy
1
尝试使用更大的数组进行计时,并且不要将数组创建时间包含在计时中。目前,你的一些测试主要是测量每个调用的开销,而有些测试并没有反映出随着数组变得越来越大会发生的明显减速情况。 - user2357112
2
另外,你收到的两个答案都会认为[1, 2, 2]等同于[1, 1, 2]。这是你想要的吗?看起来不是。我建议使用你的compare2 - user2357112
1
谢谢,我改进了代码以反映大数组的实际减速情况。实际上,我的数组没有重复项,不像我在最开始所说的那样。 - Andy
2个回答

4

Numpy是一组集合操作。

import numpy as np
import numpy.lib.arraysetops as aso

a=np.array([2, 1, 3, 3, 3])
b=np.array([1, 2, 3, 3, 3])

print aso.setdiff1d(a, b)

我该如何将空数组转换为 True - Andy
旁注:setdiff1d也可以在主要的NumPy命名空间中使用,即np.setdiff1d(至少在库的最新版本中是这样)。 - Alex Riley

1
为了确定两个数组是否包含相同类型的元素,在这种情况下是 [1,2,3],你可以进行以下操作:
import numpy as np
a=np.array([2, 1, 3, 3, 3])
b=np.array([1, 2, 3, 3, 3])

set(a) == set(b)
# True

我认为集合可以去除重复项。 - Nick Bartlett
1
是的,它确实可以,尽管原帖作者只想查看数组是否包含1、2、3。 - ODiogoSilva
1
如果OP真的想要最快的方法来做这件事,最好还是在numpy内部使用它提供的工具,因为对于大型numpy数组来说,这些工具可能是最快的。话虽如此,如果OP真的想要最快的方法,那么他们需要自己想出有意义的测试用例。 - Marius

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接