अजगर सुन्न () काम कैसे करता है?


94

मैं numpyप्रलेखन के माध्यम से खेल रहा हूं और खुदाई कर रहा हूं और मैं कुछ जादू में आया हूं। अर्थात् मैं बात कर रहा हूँ numpy.where():

>>> x = np.arange(9.).reshape(3, 3)
>>> np.where( x > 5 )
(array([2, 2, 2]), array([0, 1, 2]))

वे आंतरिक रूप से कैसे प्राप्त करते हैं कि आप x > 5एक विधि में कुछ करने में सक्षम हैं ? मुझे लगता है कि इसका कुछ लेना देना है __gt__लेकिन मैं एक विस्तृत विवरण की तलाश में हूं।

जवाबों:


75

वे आंतरिक रूप से कैसे प्राप्त करते हैं कि आप एक विधि में x> 5 जैसे कुछ पास करने में सक्षम हैं?

संक्षिप्त उत्तर यह है कि वे नहीं करते हैं।

किसी भी प्रकार की तार्किक कार्रवाई किसी भी सरणी पर एक बूलियन सरणी देता है। (यानी __gt__, __lt__आदि सभी बूलियन सरणियों को लौटाते हैं जहां दी गई स्थिति सत्य है)।

उदाहरण के लिए

x = np.arange(9).reshape(3,3)
print x > 5

पैदावार:

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

यह एक ही कारण है कि क्यों कुछ if x > 5:एक ValueError की तरह है अगर xएक संख्यात्मक सरणी है। यह सही / गलत मूल्यों की एक सरणी है, एक भी मूल्य नहीं है।

इसके अलावा, सुन्न सरणियों को बूलियन सरणियों द्वारा अनुक्रमित किया जा सकता है। जैसे x[x>5]पैदावार [6 7 8], इस मामले में।

ईमानदारी से, यह काफी दुर्लभ है जो आपको वास्तव में चाहिए numpy.whereलेकिन यह केवल उन संकेतों को वापस करता है जहां एक बूलियन सरणी है True। आमतौर पर आप वही कर सकते हैं जो आपको साधारण बूलियन इंडेक्सिंग के साथ चाहिए।


10
बस का कहना है कि numpy.where2 'परिचालन मोड', पहले एक रिटर्न की क्या ज़रूरत है indices, जहां condition is Trueऔर वैकल्पिक पैरामीटर अगर xऔर yमौजूद हैं (के रूप में ही आकार condition, या इस तरह के आकार के broadcastable!), यह से मूल्यों को वापस आ जाएगी xजब condition is Trueअन्यथा से y। तो यह whereअधिक बहुमुखी बनाता है और इसे अधिक बार उपयोग करने में सक्षम बनाता है। धन्यवाद
खाने के

1
वहाँ भी का उपयोग कर कुछ मामलों में भूमि के ऊपर हो सकता है __getitem__की वाक्य रचना []के ऊपर या तो numpy.whereया numpy.take। के बाद __getitem__से भी टुकड़ा करने की क्रिया का समर्थन किया है, वहाँ कुछ उपरि है। मैंने पायथन पंडों डेटा संरचनाओं के साथ काम करते समय और बहुत बड़े स्तंभों को तार्किक रूप से अनुक्रमित करते हुए ध्यान देने योग्य गति अंतर देखा है। उन मामलों में, आप टुकड़ा करने की क्रिया है, तो जरूरत नहीं है, तो takeऔर whereबेहतर वास्तव में कर रहे हैं।
Ely

24

पुराना उत्तर यह भ्रामक है। यह आपको (उन सभी को) जहां आपकी प्रतिमा सत्य है, का स्थान देता है।

इसलिए:

>>> a = np.arange(100)
>>> np.where(a > 30)
(array([31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
       48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
       65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
       82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98,
       99]),)
>>> np.where(a == 90)
(array([90]),)

a = a*40
>>> np.where(a > 1000)
(array([26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
       43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
       60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,
       77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
       94, 95, 96, 97, 98, 99]),)
>>> a[25]
1000
>>> a[26]
1040

मैं इसे list.index () के विकल्प के रूप में उपयोग करता हूं, लेकिन इसके कई अन्य उपयोग भी हैं। मैंने इसे 2 डी सरणियों के साथ कभी उपयोग नहीं किया है।

http://docs.scipy.org/doc/numpy/reference/generated/numpy.where.html

नया उत्तर ऐसा लगता है कि व्यक्ति कुछ अधिक मौलिक पूछ रहा था।

सवाल यह था कि आप एक ऐसी चीज़ को कैसे लागू कर सकते हैं जो एक फ़ंक्शन (जैसे जहां) को यह जानने की अनुमति देता है कि क्या अनुरोध किया गया था।

पहले ध्यान दें कि किसी भी तुलना ऑपरेटर को कॉल करना एक दिलचस्प बात है।

a > 1000
array([False, False, False, False, False, False, False, False, False,
       False, False, False, False, False, False, False, False, False,
       False, False, False, False, False, False, False, False,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True,  True,  True,  True,  True,  True,
        True`,  True,  True,  True,  True,  True,  True,  True,  True,  True], dtype=bool)`

यह "__gt__" विधि को ओवरलोड करके किया जाता है। उदाहरण के लिए:

>>> class demo(object):
    def __gt__(self, item):
        print item


>>> a = demo()
>>> a > 4
4

जैसा कि आप देख सकते हैं, "a> 4" वैध कोड था।

आप सभी ओवरलोड कार्यों की पूरी सूची और प्रलेखन यहां प्राप्त कर सकते हैं: http://docs.python.org/reference/datodod.html

कुछ ऐसा जो अविश्वसनीय है कि ऐसा करना कितना सरल है। अजगर में सभी ऑपरेशन इस तरह से किए जाते हैं। कह ए> बी एक के बराबर है। जीईटी (बी)!


3
यह तुलना ऑपरेटर ओवरलोडिंग अधिक जटिल तार्किक अभिव्यक्तियों के साथ अच्छी तरह से काम नहीं करता है - उदाहरण के लिए मैं ऐसा नहीं कर सकता np.where(a > 30 and a < 50)या np.where(30 < a < 50)क्योंकि यह बूलियन्स के दो सरणियों के तार्किक और मूल्यांकन का प्रयास करने के लिए समाप्त होता है, जो बहुत व्यर्थ है। क्या ऐसी स्थिति के साथ लिखने का कोई तरीका है np.where?
द्विविवाह

@meowsqueaknp.where((a > 30) & (a < 50))
tibalt

क्यों np.where () आपके उदाहरण में एक सूची लौटा रहा है?
एंड्रियास यांकोपोलस

0

np.whereलम्बाई का एक टुप्पल सुन्न ndarray के आयाम के बराबर होता है, जिस पर इसे (दूसरे शब्दों में ndim) कहा जाता है और tuple का प्रत्येक आइटम प्रारंभिक ndray में उन सभी मानों के सूचकांकों का एक सुन्न ndarray है जिसके लिए स्थिति सही है। (कृपया आकार के साथ आयाम को भ्रमित न करें)

उदाहरण के लिए:

x=np.arange(9).reshape(3,3)
print(x)
array([[0, 1, 2],
      [3, 4, 5],
      [6, 7, 8]])
y = np.where(x>4)
print(y)
array([1, 2, 2, 2], dtype=int64), array([2, 0, 1, 2], dtype=int64))


y लंबाई 2 का एक टपल है क्योंकि x.ndim2. टुपल में 1 आइटम में 4 से अधिक सभी तत्वों की पंक्ति संख्या होती है और 2 आइटम में 4 से अधिक सभी आइटमों के कॉलम नंबर होते हैं। जैसा कि आप देख सकते हैं, [1,2,2] , 2] 5,6,7,8 की पंक्ति संख्या से मेल खाती है और [2,0,1,2] 5,6,7,8 के स्तंभ संख्याओं से मेल खाती है। नोटरी को पहले आयाम (पंक्ति-वार) के साथ निकाला गया है )।

इसी तरह,

x=np.arange(27).reshape(3,3,3)
np.where(x>4)


लंबाई 3 का एक टपल लौटाएगा क्योंकि x के 3 आयाम हैं।

लेकिन रुको, वहाँ np.where के लिए और अधिक है!

जब दो अतिरिक्त तर्क जोड़े जाते हैं np.where; यह उन सभी जोड़ीदार पंक्ति-स्तंभ संयोजनों के लिए एक प्रतिस्थापित ऑपरेशन करेगा जो उपरोक्त टुपल द्वारा प्राप्त किए गए हैं।

x=np.arange(9).reshape(3,3)
y = np.where(x>4, 1, 0)
print(y)
array([[0, 0, 0],
   [0, 0, 1],
   [1, 1, 1]])
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.