So sánh hai mảng NumPy cho sự bình đẳng, yếu tố khôn ngoan


252

Cách đơn giản nhất để so sánh hai mảng NumPy cho đẳng thức (trong đó đẳng thức được định nghĩa là: A = B iff cho tất cả các chỉ số i A[i] == B[i]:)?

Đơn giản chỉ cần sử dụng ==cung cấp cho tôi một mảng boolean:

 >>> numpy.array([1,1,1]) == numpy.array([1,1,1])

array([ True,  True,  True], dtype=bool)

Tôi có phải andcác yếu tố của mảng này để xác định xem các mảng có bằng nhau không, hoặc có cách nào đơn giản hơn để so sánh không?

Câu trả lời:


379
(A==B).all()

kiểm tra xem tất cả các giá trị của mảng (A == B) có đúng không.

Lưu ý: có thể bạn cũng muốn kiểm tra hình dạng A và B, chẳng hạn như A.shape == B.shape

Các trường hợp đặc biệt và giải pháp thay thế (từ câu trả lời của dbaupp và bình luận của yoavram)

Cần lưu ý rằng:

  • giải pháp này có thể có một hành vi lạ trong một trường hợp cụ thể: nếu một Ahoặc Btrống và một phần tử khác chứa một phần tử duy nhất, thì nó sẽ trả về True. Vì một số lý do, phép so sánh A==Btrả về một mảng trống mà alltoán tử trả về True.
  • Một rủi ro khác là nếu ABkhông có hình dạng giống nhau và không thể phát sóng được, thì phương pháp này sẽ gây ra lỗi.

Tóm lại, nếu bạn nghi ngờ ABđịnh hình hoặc đơn giản là muốn an toàn: sử dụng một trong các chức năng chuyên biệt:

np.array_equal(A,B)  # test if same shape, same elements values
np.array_equiv(A,B)  # test if broadcastable shape, same elements values
np.allclose(A,B,...) # test if same shape, elements have close enough values

25
Bạn hầu như luôn muốn np.array_equalIME. (A==B).all()sẽ sụp đổ nếu A và B có độ dài khác nhau . Kể từ numpy 1.10, == đưa ra cảnh báo khấu hao trong trường hợp này .
Wilfred Hughes

Bạn đã có một điểm tốt, nhưng trong trường hợp tôi có nghi ngờ về hình dạng, tôi thường thích trực tiếp kiểm tra nó, trước giá trị. Sau đó, lỗi rõ ràng là trên các hình có ý nghĩa hoàn toàn khác với các giá trị khác nhau. Nhưng điều đó có thể phụ thuộc vào từng trường hợp sử dụng
Juh_

2
rủi ro khác là nếu các mảng chứa nan. Trong trường hợp đó, bạn sẽ nhận được Sai vì nan! = Nan
Vincenzooo

1
Tốt để chỉ ra nó. Tuy nhiên, tôi nghĩ rằng điều này là hợp lý bởi vì nan!=nannó ngụ ý rằng array(nan)!=array(nan).
Juh_

Tôi không hiểu hành vi này: import numpy as np H = 1/np.sqrt(2)*np.array([[1, 1], [1, -1]]) #hadamard matrix np.array_equal(H.dot(H.T.conj()), np.eye(len(H))) # checking if H is an unitary matrix or not H là một ma trận đơn nhất, vì vậy H x H.T.conjlà một ma trận danh tính. Nhưng np.array_equaltrả về Sai
Dex

91

Các (A==B).all()giải pháp rất gọn gàng, nhưng có một số tích hợp chức năng cho nhiệm vụ này. Cụ thể array_equal, allclosearray_equiv.

(Mặc dù, một số thử nghiệm nhanh timeitdường như chỉ ra rằng (A==B).all()phương pháp này là nhanh nhất, có một chút đặc biệt, do nó phải phân bổ một mảng hoàn toàn mới.)


15
bạn đúng, ngoại trừ nếu một trong các mảng được so sánh trống, bạn sẽ nhận được câu trả lời sai (A==B).all(). Ví dụ: thử (np.array([1])==np.array([])).all()Truenp.array_equal(np.array([1]), np.array([]))False
:,

1
Tôi chỉ phát hiện ra sự khác biệt hiệu suất này quá. Thật lạ vì nếu bạn có 2 mảng hoàn toàn khác nhau (a==b).all()thì vẫn nhanh hơn np.array_equal(a, b)(có thể vừa kiểm tra một yếu tố duy nhất và đã thoát).
Aidan Kane

np.array_equalcũng làm việc với lists of arraysdicts of arrays. Đây có thể là một lý do cho một hiệu suất chậm hơn.
Bernhard

Cảm ơn rất nhiều cho hàm allclose, đó là những gì tôi cần cho các phép tính số . Nó so sánh sự bằng nhau của các vectơ trong một dung sai . :)
yêu.by.Jesus

Lưu ý rằng np.array_equiv([1,1,1], 1) is True. Điều này là do: Hình dạng nhất quán có nghĩa là chúng có cùng hình dạng hoặc một mảng đầu vào có thể được phát để tạo hình dạng giống như hình dạng khác.
EliadL

13

Hãy đo hiệu suất bằng cách sử dụng đoạn mã sau.

import numpy as np
import time

exec_time0 = []
exec_time1 = []
exec_time2 = []

sizeOfArray = 5000
numOfIterations = 200

for i in xrange(numOfIterations):

    A = np.random.randint(0,255,(sizeOfArray,sizeOfArray))
    B = np.random.randint(0,255,(sizeOfArray,sizeOfArray))

    a = time.clock() 
    res = (A==B).all()
    b = time.clock()
    exec_time0.append( b - a )

    a = time.clock() 
    res = np.array_equal(A,B)
    b = time.clock()
    exec_time1.append( b - a )

    a = time.clock() 
    res = np.array_equiv(A,B)
    b = time.clock()
    exec_time2.append( b - a )

print 'Method: (A==B).all(),       ', np.mean(exec_time0)
print 'Method: np.array_equal(A,B),', np.mean(exec_time1)
print 'Method: np.array_equiv(A,B),', np.mean(exec_time2)

Đầu ra

Method: (A==B).all(),        0.03031857
Method: np.array_equal(A,B), 0.030025185
Method: np.array_equiv(A,B), 0.030141515

Theo các kết quả ở trên, các phương thức numpy dường như nhanh hơn sự kết hợp của toán tử == và phương thức all () và bằng cách so sánh các phương thức numpy, phương thức nhanh nhất dường như là phương thức numpy.array_equal .


4
Bạn nên sử dụng kích thước mảng lớn hơn mất ít nhất một giây để biên dịch để tăng độ chính xác của thử nghiệm.
Vikhyat Agarwal

Điều này cũng sao chép khi thứ tự so sánh được thay đổi? hoặc khôi phục A và B ngẫu nhiên mỗi lần? Sự khác biệt này cũng có thể được giải thích từ bộ nhớ đệm của các ô A và B.
Hoặc Groman

3
Không có sự khác biệt có ý nghĩa giữa các thời gian.
Đến 마 SE

13

Nếu bạn muốn kiểm tra xem hai mảng có giống nhau shapeelementsbạn nên sử dụng np.array_equalvì đó là phương pháp được đề xuất trong tài liệu.

Hiệu suất khôn ngoan không hy vọng rằng bất kỳ kiểm tra bình đẳng sẽ đánh bại người khác, vì không có nhiều chỗ để tối ưu hóa comparing two elements. Chỉ vì lợi ích, tôi vẫn làm một số xét nghiệm.

import numpy as np
import timeit

A = np.zeros((300, 300, 3))
B = np.zeros((300, 300, 3))
C = np.ones((300, 300, 3))

timeit.timeit(stmt='(A==B).all()', setup='from __main__ import A, B', number=10**5)
timeit.timeit(stmt='np.array_equal(A, B)', setup='from __main__ import A, B, np', number=10**5)
timeit.timeit(stmt='np.array_equiv(A, B)', setup='from __main__ import A, B, np', number=10**5)
> 51.5094
> 52.555
> 52.761

Vì vậy, khá nhiều bằng nhau, không cần phải nói về tốc độ.

Các (A==B).all()hành vi khá nhiều như đoạn mã sau:

x = [1,2,3]
y = [1,2,3]
print all([x[i]==y[i] for i in range(len(x))])
> True

5

Thông thường hai mảng sẽ có một số lỗi số nhỏ,

Bạn có thể sử dụng numpy.allclose(A,B), thay vì (A==B).all(). Điều này trả về một bool Đúng / Sai


0

Bây giờ sử dụng np.array_equal. Từ tài liệu:

np.array_equal([1, 2], [1, 2])
True
np.array_equal(np.array([1, 2]), np.array([1, 2]))
True
np.array_equal([1, 2], [1, 2, 3])
False
np.array_equal([1, 2], [1, 4])
False
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.