अगर हालत मिले तो Numpy तत्वों को बदलना


94

मेरे पास एक बड़ी संख्या में सरणी है जिसे मुझे हेरफेर करने की आवश्यकता है ताकि प्रत्येक तत्व को 1 या 0 में बदल दिया जाए यदि कोई शर्त पूरी होती है (बाद में पिक्सेल मास्क के रूप में उपयोग किया जाएगा)। सरणी में लगभग 8 मिलियन तत्व हैं और मेरी मौजूदा विधि में कमी पाइपलाइन के लिए बहुत लंबा है:

for (y,x), value in numpy.ndenumerate(mask_data): 

    if mask_data[y,x]<3: #Good Pixel
        mask_data[y,x]=1
    elif mask_data[y,x]>3: #Bad Pixel
        mask_data[y,x]=0

क्या कोई सुस्पष्ट कार्य है जो इसे गति देगा?


1
अगर आप क्या करना चाहते हैं mask_data[y,x]==3?
DSM

अच्छा बिंदु, यह अभी भी एक खराब पिक्सेल होगा। मैं हालत को if mask_data[y,x]>=3:
बदलूंगा

जवाबों:


128
>>> import numpy as np
>>> a = np.random.randint(0, 5, size=(5, 4))
>>> a
array([[4, 2, 1, 1],
       [3, 0, 1, 2],
       [2, 0, 1, 1],
       [4, 0, 2, 3],
       [0, 0, 0, 2]])
>>> b = a < 3
>>> b
array([[False,  True,  True,  True],
       [False,  True,  True,  True],
       [ True,  True,  True,  True],
       [False,  True,  True, False],
       [ True,  True,  True,  True]], dtype=bool)
>>> 
>>> c = b.astype(int)
>>> c
array([[0, 1, 1, 1],
       [0, 1, 1, 1],
       [1, 1, 1, 1],
       [0, 1, 1, 0],
       [1, 1, 1, 1]])

आप इसे छोटा कर सकते हैं:

>>> c = (a < 3).astype(int)

2
यह कैसे विशिष्ट स्तंभों के साथ कुछ स्तंभों को बाहर निकालने के बिना और फिर से वापस असाइन करने के लिए होता है? उदाहरण के लिए, स्तंभों में केवल तत्व [2, 3] को शर्तों को पूरा करने पर मूल्य में बदलाव करना चाहिए, जबकि अन्य कॉलम नहीं बदलेंगे, कोई भी स्थिति पूरी नहीं होती है या नहीं।
kuixiong

सच है, लेकिन केवल शून्य और लोगों के मामले के लिए। नीचे और अधिक सामान्य जवाब (दक्षता कीमत पर) देखें
borgr

89
>>> a = np.random.randint(0, 5, size=(5, 4))
>>> a
array([[0, 3, 3, 2],
       [4, 1, 1, 2],
       [3, 4, 2, 4],
       [2, 4, 3, 0],
       [1, 2, 3, 4]])
>>> 
>>> a[a > 3] = -101
>>> a
array([[   0,    3,    3,    2],
       [-101,    1,    1,    2],
       [   3, -101,    2, -101],
       [   2, -101,    3,    0],
       [   1,    2,    3, -101]])
>>>

उदाहरण के लिए, बूलियन सरणियों के साथ अनुक्रमण देखें ।


3
महान सामान, धन्यवाद! यदि आप उस मूल्य को संदर्भित करना चाहते हैं जिसे आप बदलते हैं तो आप कुछ का उपयोग कर सकते हैं a[a > 3] = -101+a[a > 3]
pexmar

1
@pexmar हालांकि यदि आप के a[a > 3] = -101+a[a > 3]बजाय आप करते हैं, a[a > 3] += -101तो सबसे अधिक संभावना है कि स्मृति रिसाव हो सकता है।
शमूएल प्रीवोस्ट

1
pexmar के पूछे जाने पर आप उस मूल्य को कैसे बदलते हैं जो आप बदलते हैं ??
जुआन

34

सबसे तेज़ (और सबसे लचीला) तरीका np.where का उपयोग करना है , जो मास्क के अनुसार दो सरणियों के बीच चयन करता है (सच्चे और झूठे मूल्यों का सरणी):

import numpy as np
a = np.random.randint(0, 5, size=(5, 4))
b = np.where(a<3,0,1)
print('a:',a)
print()
print('b:',b)

जो उत्पादन करेगा:

a: [[1 4 0 1]
 [1 3 2 4]
 [1 0 2 1]
 [3 1 0 0]
 [1 4 0 1]]

b: [[0 1 0 0]
 [0 1 0 1]
 [0 0 0 0]
 [1 0 0 0]
 [0 1 0 0]]

1
यदि शर्त पूरी नहीं होती है तो मैं सबसे अच्छा तरीका क्या होगा, अगर शर्त पूरी नहीं की जाती है, तो केवल यह है कि शर्त पूरी करने के बाद मूल मूल्य को छोड़ दें, अगर मूल संख्या नहीं है, तो ....
अभिषेक सेनगुप्ता

1
सभी मानों को एक में बदलने के लिए, जो तब छोटे होते हैं 3 और बाकी को वैसे ही रखें, जैसे कि उपयोग करेंa[a<3] = 0
मार्कस डट्सचके जूल 3

3

आप इस तरह से एक कदम में अपने मुखौटा सरणी बना सकते हैं

mask_data = input_mask_data < 3

यह एक बूलियन सरणी बनाता है जिसे तब पिक्सेल मास्क के रूप में इस्तेमाल किया जा सकता है। ध्यान दें कि हमने इनपुट ऐरे (आपके कोड में) को नहीं बदला है, लेकिन मास्क डेटा को होल्ड करने के लिए एक नया एरे बनाया है - मैं इसे इस तरह से करने की सलाह दूंगा।

>>> input_mask_data = np.random.randint(0, 5, (3, 4))
>>> input_mask_data
array([[1, 3, 4, 0],
       [4, 1, 2, 2],
       [1, 2, 3, 0]])
>>> mask_data = input_mask_data < 3
>>> mask_data
array([[ True, False, False,  True],
       [False,  True,  True,  True],
       [ True,  True, False,  True]], dtype=bool)
>>> 

1
हां। यदि ओपी वास्तव में 0s और 1s चाहता है, तो वह .astype(int)या का उपयोग कर सकता है *1, लेकिन एक सरणी है Trueऔर Falseयह जितना अच्छा है उतना ही अच्छा है।
DSM

-4

मुझे यकीन नहीं है कि मैंने आपके प्रश्न को समझा है, लेकिन अगर आप लिखते हैं:

mask_data[:3, :3] = 1
mask_data[3:, 3:] = 0

यह मास्क डेटा के सभी मूल्यों को बनाएगा जिसका x और y इंडेक्स 3 से कम 1 के बराबर हो और बाकी सभी 0 के बराबर हों

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