在Matlab中,内置isequal
检查两个数组是否相等。如果它们不相等,这可能会非常快,因为一旦存在差异,实施可能会停止检查:
>> A = zeros(1e9, 1, 'single');
>> B = A(:);
>> B(1) = 1;
>> tic; isequal(A, B); toc;
Elapsed time is 0.000043 seconds.
Python / numpy中是否有任何等价? all(A==B)
或all(equal(A, B))
要慢得多,因为它会比较所有元素,即使初始元素不同:
In [13]: A = zeros(1e9, dtype='float32')
In [14]: B = A.copy()
In [15]: B[0] = 1
In [16]: %timeit all(A==B)
1 loops, best of 3: 612 ms per loop
是否有任何numpy等价物?它应该很容易在C中实现,但在Python中实现起来很慢,因为这是我们不想要广播的情况,因此它需要一个显式循环。
修改
array_equal
看起来像我想要的那样。但是,不比all(A==B)
更快,因为它不是内置的,只是一个简短的Python函数A==B
。因此,它无法满足我对快速检查的需求。
In [12]: %timeit array_equal(A, B)
1 loops, best of 3: 623 ms per loop
答案 0 :(得分:6)
首先,应该注意的是,在OP的示例中,数组具有相同的元素,因为B=A[:]
只是数组的视图,因此:
>>> print A[0], B[0]
1.0, 1.0
但是,尽管测试不合适,但基本的抱怨是正确的:Numpy没有短路等效性检查。
可以从the source轻松看到allclose
,array_equal
和array_equiv
的所有内容只是all(A==B)
上的变体,以匹配各自的详细信息,不是很明显。
numpy的一个优点是切片只是视图,因此非常快,因此可以相当容易地编写自己的短路比较(我不是说这是理想的,但确实有效):
from numpy import *
A = zeros(1e8, dtype='float32')
B = A[:]
B[0] = 1
C = array(B)
C[0] = 2
D = array(A)
D[-1] = 2
def short_circuit_check(a, b, n):
L = len(a)/n
for i in range(n):
j = i*L
if not all(a[j:j+L]==b[j:j+L]):
return False
return True
In [26]: %timeit short_circuit_check(A, C, 100) # 100x faster
1000 loops, best of 3: 1.49 ms per loop
In [27]: %timeit all(A==C)
1 loops, best of 3: 158 ms per loop
In [28]: %timeit short_circuit_check(A, D, 100)
10 loops, best of 3: 144 ms per loop
In [29]: %timeit all(A==D)
10 loops, best of 3: 160 ms per loop