Numpy fast check for complete array equality, e.g. Matlabs isequal

In Matlab, the built-in isequal checks to see if two arrays are equal. If they are not equal, this can be very fast, because the implementation seems to stop checking as soon as the difference exists:

 >> A = zeros(1e9, 1, 'single'); >> B = A(:); >> B(1) = 1; >> tic; isequal(A, B); toc; Elapsed time is 0.000043 seconds. 

Is there any equivalent in Python / numpy? all(A==B) or all(equal(A, B)) much slower as it compares all elements, even if the original is different:

 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 

Is there any numpy equivalent? It should be very easy to implement in C, but slowly implemented in Python, because this is the case when we do not want to translate, so this will require an explicit loop.

Edit:

It seems that array_equal doing what I want. However, this is not faster than all(A==B) because it is not built-in, but simply a short Python function that executes A==B So this does not meet my need for a quick check.

 In [12]: %timeit array_equal(A, B) 1 loops, best of 3: 623 ms per loop 
+6
source share
1 answer

Firstly, it should be noted that in the OP example, arrays have the same elements, because B=A[:] is just an array representation, therefore:

 >>> print A[0], B[0] 1.0, 1.0 

But, although the test does not work, the main complaint is true: Numpy does not have a short circuit equivalence check.

It’s easy to see from the source that all allclose , array_equal and array_equiv are just variations on all(A==B) to match their respective details and not noticeable faster.

The advantage of numpy is that the slices are just views, and therefore very fast, so you can write your own short circuit quite easily (I'm not saying that this is ideal, but it works):

 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 
+5
source

Source: https://habr.com/ru/post/976442/


All Articles