समानता, तत्व-वार के लिए दो NumPy सरणियों की तुलना करना


252

समानता के लिए दो NumPy सरणियों की तुलना करने का सबसे सरल तरीका क्या है (जहां समानता को सभी सूचकांकों के लिए A = B iff के रूप में परिभाषित किया गया है:) A[i] == B[i]?

बस ==मुझे एक बूलियन सरणी का उपयोग करके :

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

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

क्या मुझे andइस सरणी के तत्वों को निर्धारित करना है कि क्या सरणियाँ समान हैं, या तुलना करने का एक सरल तरीका है?

जवाबों:


380
(A==B).all()

यदि सरणी के सभी मान (A == B) सत्य हैं तो परीक्षण करें।

नोट: शायद आप भी ए और बी आकार का परीक्षण करना चाहते हैं, जैसे कि A.shape == B.shape

विशेष मामले और विकल्प (dbaupp के उत्तर और योराम की टिप्पणी से)

इस बात पर ध्यान दिया जाना चाहिए कि:

  • इस समाधान एक विशेष मामले में एक अजीब व्यवहार हो सकता है: यदि या तो Aया Bखाली है और एक दूसरे को एक भी तत्व होता है, तो इसे वापस True। किसी कारण से, तुलना A==Bएक खाली सरणी देता है, जिसके लिए allऑपरेटर वापस लौटता है True
  • एक और खतरा है, तो है Aऔर Bएक ही आकार नहीं है और broadcastable नहीं हैं, तो इस दृष्टिकोण एक त्रुटि बढ़ा देंगे।

निष्कर्ष में, यदि आपको संदेह है Aऔर Bआकार या बस सुरक्षित होना चाहते हैं: विशेष कार्यों में से एक का उपयोग करें:

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

26
आप लगभग हमेशा np.array_equalIME चाहते हैं । ए और बी अलग लंबाई है अगर दुर्घटना(A==B).all() होगी । जैसा कि 1.10 के बराबर है, == इस मामले में एक पदावनति चेतावनी देता है
विल्फ्रेड ह्यूजेस

आपको एक अच्छा बिंदु मिला है, लेकिन मामले में मुझे उस आकार पर संदेह है जिसे मैं आमतौर पर मूल्य से पहले इसे सीधे परीक्षण करना पसंद करता हूं। फिर त्रुटि स्पष्ट रूप से उन आकृतियों पर होती है, जिनके विभिन्न मूल्य होने की तुलना में पूरी तरह से अलग अर्थ होता है। लेकिन यह शायद प्रत्येक उपयोग के मामले पर निर्भर करता है
Juh_

2
एक और जोखिम है यदि सरणियों में नैनो शामिल है। उस स्थिति में आपको झूठी मिल जाएगी क्योंकि नैन! = नान
विन्सेन्ज़ो

1
यह इंगित करने के लिए अच्छा है। हालाँकि, मुझे लगता है कि यह तर्कसंगत है क्योंकि nan!=nanइसका मतलब है कि array(nan)!=array(nan)
जुह_

मैं इस व्यवहार को नहीं समझता: 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 एक एकात्मक मैट्रिक्स है, इसलिए H x H.T.conjएक पहचान मैट्रिक्स है। लेकिन np.array_equalझूठे
डेक्स

91

(A==B).all()समाधान बहुत साफ है, लेकिन इस कार्य के लिए कुछ बिल्ट-इन कार्य कर रहे हैं। अर्थात् array_equal, allcloseऔर array_equiv

(हालांकि, कुछ त्वरित परीक्षण से timeitप्रतीत होता है कि (A==B).all()विधि सबसे तेज़ है, जो थोड़ी अजीब है, इसे देखते हुए इसे एक नया सरणी आवंटित करना होगा।)


15
आप सही कह रहे हैं, सिवाय इसके कि यदि किसी में से एक भी सारणी खाली है तो आपको गलत उत्तर मिलेगा (A==B).all()। उदाहरण के लिए, कोशिश करें: (np.array([1])==np.array([])).all()यह देता है True, जबकि np.array_equal(np.array([1]), np.array([]))देता हैFalse
योवराम

1
मुझे इस प्रदर्शन अंतर का भी पता चला। यह अजीब है क्योंकि अगर आपके पास 2 सरणियां हैं जो पूरी तरह से अलग हैं (a==b).all(), तो अभी भी की तुलना में तेज है np.array_equal(a, b)(जो कि एक ही तत्व की जांच कर सकता है और बाहर निकल सकता है)।
ऐदन केन

np.array_equalके साथ भी काम करता है lists of arraysऔर dicts of arrays। यह धीमे प्रदर्शन का एक कारण हो सकता है।
बर्नहार्ड

फ़ंक्शन के लिए बहुत बहुत धन्यवाद allclose, यही मुझे संख्यात्मक गणनाओं के लिए आवश्यक है । यह सहिष्णुता के भीतर वैक्टर की समानता की तुलना करता है । :)
love.by.Jesus

ध्यान दें np.array_equiv([1,1,1], 1) is True। इसका कारण यह है: आकार सुसंगत का अर्थ है कि वे या तो एक ही आकार हैं, या एक इनपुट सरणी को दूसरे के समान आकार बनाने के लिए प्रसारित किया जा सकता है।
एलियाडल

13

आइए कोड के निम्नलिखित टुकड़े का उपयोग करके प्रदर्शन को मापें।

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)

उत्पादन

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

ऊपर दिए गए परिणामों के अनुसार, खस्ता विधियाँ == ऑपरेटर और सभी () विधि के संयोजन की तुलना में तेज़ लगती हैं और खस्ता तरीकों की तुलना करने से सबसे तेज़ लगता है numpy.array_equal विधि।


4
आपको एक बड़े सरणी आकार का उपयोग करना चाहिए जो प्रयोग की सटीकता बढ़ाने के लिए संकलन में कम से कम एक सेकंड लेता है।

जब तुलना का क्रम बदला जाता है तो क्या यह भी पुन: उत्पन्न होता है? या ए और बी को हर बार बेतरतीब ढंग से मजबूत करना? इस अंतर को ए और बी कोशिकाओं के मेमोरी कैशिंग से भी समझाया जा सकता है।
या ग्रोमन

3
इन समयों के बीच कोई सार्थक अंतर नहीं है।
एसई

13

यदि आप जांचना चाहते हैं कि क्या दो सरणियों के समान है shapeऔर elementsआपको इसका उपयोग करना चाहिए np.array_equalक्योंकि यह प्रलेखन में अनुशंसित विधि है।

प्रदर्शन-वार यह उम्मीद नहीं करते हैं कि किसी भी समानता की जांच दूसरे को हरा देगी, क्योंकि अनुकूलन के लिए बहुत जगह नहीं है comparing two elements। बस, मैंने अभी भी कुछ परीक्षण किए हैं।

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

तो बहुत ज्यादा समान, गति के बारे में बात करने की कोई जरूरत नहीं है।

(A==B).all()बर्ताव काफी निम्नलिखित कोड का टुकड़ा के रूप में:

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

5

आमतौर पर दो सरणियों में कुछ छोटी संख्यात्मक त्रुटियां होंगी,

आप उपयोग कर सकते हैं numpy.allclose(A,B), के बजाय (A==B).all()। यह एक बूल ट्रू / गलत रिटर्न देता है


0

अब उपयोग करें np.array_equal। प्रलेखन से:

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
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.