2009-10-23 34 views
37

कोई भी इस समस्या तक कभी आया है? आइए मान लें कि आपके पास निम्नलिखितNumPy: दो Arrays में तत्वों की तुलना

a = array([1,2,3,4,5,6]) 
b = array([1,4,5]) 

क्या बी में मौजूद तत्वों की तुलना करने का कोई तरीका है? उदाहरण के लिए,

c = a == b # Wishful example here 
print c 
array([1,4,5]) 
# Or even better 
array([True, False, False, True, True, False]) 

मैं लूप से बचने की कोशिश कर रहा हूं क्योंकि इसमें लाखों तत्वों के साथ उम्र लगेगी। कोई विचार?

चीयर्स

+0

आपके पास सरणी में कौन सा डेटा है? इंडेक्स की तरह अद्वितीय पूर्णांक उदाहरण की तरह? – u0b34a0f6ae

उत्तर

47

वास्तव में, वहाँ इनमें से किसी भी से भी सरल समाधान:

import numpy as np 

a = array([1,2,3,4,5,6]) 
b = array([1,4,5]) 

c = np.in1d(a,b) 

जिसके परिणामस्वरूप सी जाती है:

array([ True, False, False, True, True, False], dtype=bool) 
+6

क्या इसका कोई "लगभग_equal" संस्करण है? आप समानता के परीक्षण के लिए उपयोग की जाने वाली स्थिति निर्दिष्ट कर सकते हैं? – endolith

-2

आपका उदाहरण स्थापित की तरह व्यवहार, सरणी में और अधिक के बारे में अस्तित्व की देखभाल सही जगह पर सही तत्व होने से निकलता है। Numpy अपने गणितीय सरणी और matrices के साथ यह अलग करता है, यह आपको केवल सही जगह पर वस्तुओं के बारे में बताएगा। क्या आप यह काम कर सकते हैं?

>>> import numpy 
>>> a = numpy.array([1,2,3]) 
>>> b = numpy.array([1,3,3]) 
>>> a == b 
array([ True, False, True], dtype=bool) 
+0

क्षमा करें, यदि आप इसे आजमाते हैं तो यह उदाहरण काम नहीं करता है; इसके अलावा, आपको पहले सरणी को सॉर्ट करना होगा। – dalloliogm

+0

@ डेलोलिगोम: उह, मैंने अपने इंटरैक्टिव सत्र से कॉपी किया है, कम से कम यह पाइथन और न्यूम्पी के कुछ संस्करणों के लिए बिल्कुल ठीक तरह से काम करता है। – u0b34a0f6ae

+0

ठीक है, लेकिन यह काम नहीं करता है अगर दो सरणी अलग-अलग लंबाई हैं; किसी भी मामले में, आपको उन्हें पहले क्रमबद्ध करना होगा (सरणी ([1,2,3]) == सरणी ([2,3,1]) आज़माएं। वह जानना चाहता है कि किसी सरणी के कौन से तत्व दूसरे में मौजूद हैं। – dalloliogm

2

आपके उत्तर kaizer.se के लिए धन्यवाद। यह काफी नहीं है जो मैं खोज रहा था, लेकिन एक दोस्त से सुझाव के साथ और आपने जो कहा वह मैं निम्नलिखित के साथ आया।

import numpy as np 

a = np.array([1,4,5]).astype(np.float32) 
b = np.arange(10).astype(np.float32) 

# Assigning matching values from a in b as np.nan 
b[b.searchsorted(a)] = np.nan 

# Now generating Boolean arrays 
match = np.isnan(b) 
nonmatch = match == False 

यह एक बोझिल प्रक्रिया है, लेकिन यह लूप लिखने या लूप के साथ बुनाई का उपयोग करता है।

चीयर्स

+0

इस दृष्टिकोण के साथ समस्या यह है कि यह 'ए' में मौजूद मानों के लिए भी इंडेक्स देता है जो' बी' में मौजूद नहीं है (साथ ही साथ अन्य मामलों में डुप्लिकेट इंडेक्स)। उदाहरण के लिए: 'numpy.searchsorted ([1, 2], [1.2, 1.3 ]) 'रिटर्न' [1, 1] 'जो ओपी के लिए उपयुक्त नहीं है। – sirfz

2

Numpy एक सेट समारोह numpy.setmember1d() कि क्रमबद्ध और uniqued सरणियों पर काम करता है और वास्तव में बूलियन सरणी कि आप चाहते हैं देता है। यदि इनपुट एरे मानदंडों से मेल नहीं खाते हैं तो आपको सेट प्रारूप में रूपांतरित करने और परिणाम पर परिवर्तन को बदलने की आवश्यकता होगी।

import numpy as np 
a = np.array([6,1,2,3,4,5,6]) 
b = np.array([1,4,5]) 

# convert to the uniqued form 
a_set, a_inv = np.unique1d(a, return_inverse=True) 
b_set = np.unique1d(b) 
# calculate matching elements 
matches = np.setmea_set, b_set) 
# invert the transformation 
result = matches[a_inv] 
print(result) 
# [False True False False True True False] 

संपादित करें: दुर्भाग्य numpy में setmember1d विधि वास्तव में अक्षम है। आपके द्वारा प्रस्तावित खोज सॉर्ट और असाइन की गई विधि तेज़ी से काम करती है, लेकिन यदि आप सीधे असाइन कर सकते हैं तो आप सीधे परिणाम के लिए असाइन कर सकते हैं और बहुत सारी अनावश्यक प्रतिलिपि से बच सकते हैं। यदि बी में कुछ भी नहीं है तो आपकी विधि भी असफल हो जाएगी। निम्नलिखित उन त्रुटियों को सही:

result = np.zeros(a.shape, dtype=np.bool) 
idxs = a.searchsorted(b) 
idxs = idxs[np.where(idxs < a.shape[0])] # Filter out out of range values 
idxs = idxs[np.where(a[idxs] == b)] # Filter out where there isn't an actual match 
result[idxs] = True 
print(result) 

मेरे बेंचमार्क अपने दृष्टिकोण और 1M तत्व एक और 100 तत्व ख पर numpy setmember1d के लिए 109ms के लिए 91us बनाम 6.6ms में यह दिखा।

+0

यह एक अच्छा समाधान है। मैं आपके सुझाव का प्रयास करूंगा और जो मैंने अभी लिखा है, यह देखने के लिए कि गति में अधिक इष्टतम क्या है। बहुत से लोग आपके लिए धन्यवाद मदद करें! – ebressert

+0

मैंने जो विधि लिखा है वह थोड़ा तेज़ है। 10000 तत्व सरणी के लिए आईपीथॉन में टाइमिट का उपयोग करने में लगने वाला समय लगभग 3 माइक्रोन है। setmember1d m विधि 3 एमएस लिया। मुझे लगता है कि आपकी विधि अधिक सुरुचिपूर्ण है, लेकिन मुझे गति की आवश्यकता है। – ebressert

+0

आप तीसरी पंक्ति में एक कोष्ठक बंद करना भूल गए। कुछ कंप्यूटर विज्ञान प्रोफेसर इसे नोटिस करने से पहले आपको इसे ठीक करना चाहिए ... – dalloliogm

18

np.intersect1d का उपयोग करें।

#!/usr/bin/env python 
import numpy as np 
a = np.array([1,2,3,4,5,6]) 
b = np.array([1,4,5]) 
c=np.intersect1d(a,b) 
print(c) 
# [1 4 5] 

ध्यान दें कि np.intersect1d गलत जवाब देता है यदि ए या बी में गैर-तत्व तत्व हैं। उस मामले में np.intersect1d_nu का उपयोग करें।

np.setdiff1d, setxor1d, setmember1d, और union1d भी है। Numpy Example List With Doc

+0

+1: बढ़िया। इस कार्य के लिए सही कार्य। – tom10

0

ईब्रेसेट, your answer तब तक काम नहीं करेगा जब तक कि बी का उप-समूह नहीं है (और ए और बी सॉर्ट किए जाते हैं)। अन्यथा खोज किए गए झूठे सूचकांक वापस आ जाएंगे।मैं ऐसी ही कुछ करना था, और अपने कोड के साथ संयोजन है कि:

# Assume a and b are sorted 
idxs = numpy.mod(b.searchsorted(a),len(b)) 
idxs = idxs[b[idxs]==a] 
b[idxs] = numpy.nan 
match = numpy.isnan(b) 
संबंधित मुद्दे