Python Numpy快速检查完整的数组相等性,如Matlabs isequal
在Matlab中,内置的isequal检查两个数组是否相等。如果它们不相等,这可能会非常快,因为实现可能会在出现差异时立即停止检查:Python Numpy快速检查完整的数组相等性,如Matlabs isequal,python,arrays,numpy,Python,Arrays,Numpy,在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中
>> 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)
快,因为它不是一个内置函数,只是一个执行A==B
的短Python函数。所以它不能满足我快速检查的需要
首先,应该注意,在OP的示例中,数组具有相同的元素,因为
B=A[:]
只是数组的一个视图,因此:
>>> print A[0], B[0]
1.0, 1.0
但是,尽管测试并不合适,但基本抱怨是正确的:Numpy没有短路等效性检查
我们可以很容易地从中看出,所有的allclose
、array_equal
和array_equal
都只是all(A==B)
的变体,以匹配各自的细节,并且不会更快。
numpy的一个优点是,切片只是视图,因此速度非常快,因此可以相当轻松地编写自己的短路比较(我不是说这很理想,但它确实有效):
此外,“all(equal(A,B))的速度要慢得多,因为它比较所有元素,即使初始元素不同”是不正确的,
all
如果遇到False
,将提前返回,就像any
在遇到True
@Cyber但在all
甚至开始之前,equal(A,B)将提前返回一样
已经比较了所有元素。哦,好吧,我明白你的意思了,我错了。@Cyber编辑的问题array_equal
看起来很棒,但实际上只是一个简短的Python函数,它不满足a==B
的要求,因此不符合fast
的要求。在问题中将其更改为B=A.copy()
。一定是被名单弄糊涂了。
>>> print A[0], B[0]
1.0, 1.0
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