【问题标题】:Fastest way of comparing two numpy arrays比较两个numpy数组的最快方法
【发布时间】:2015-07-04 12:36:33
【问题描述】:

我有两个数组:

>>> 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”方法是最快的。

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

EDIT2 正如 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?
  • 对两者进行排序,然后比较我猜。
  • 在更大的阵列上尝试计时,并且不要在计时中包含阵列创建时间。目前,您的一些测试主要是测量每次调用的开销,并且您的一些测试并未反映较大数组出现的急剧减速。
  • 另外,您收到的两个答案都认为[1, 2, 2] 等同于[1, 1, 2]。那是你要的吗?看起来不像。我建议您使用compare2
  • 谢谢,我改进了它以反映大型阵列的真正减速。好吧,实际上我有没有重复的数组,不像我在最上面所说的那样。

标签: python arrays performance python-2.7 numpy


【解决方案1】:

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
  • 旁白:setdiff1d 也可用于 NumPy 主命名空间,即np.setdiff1d(至少在库的最新版本中)。
【解决方案2】:

要查看两个数组是否包含相同类型的元素,在本例中为 [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

【讨论】:

  • 我认为设置删除重复项。
  • 是的,虽然 OP 只想查看数组是否包含 1,2,3
  • 如果 OP 真的想要最快的方法来做到这一点,最好留在numpy 内并使用它提供的工具,因为这些对于大型 numpy 数组可能是最快的。也就是说,如果 OP 真的想要最快的方法,那么他们需要提出有意义的测试用例。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-19
  • 2013-06-18
相关资源
最近更新 更多