मैं किसी दी गई शर्त के तत्वों का चयन कैसे करूं?


156

मैं एक numpy सरणी है मान लीजिए x = [5, 2, 3, 1, 4, 5], y = ['f', 'o', 'o', 'b', 'a', 'r']। मैं उन तत्वों के yअनुरूप तत्वों का चयन करना चाहता हूं xजिनमें 1 से अधिक और 5 से कम हो।

मैंने कोशिश की

x = array([5, 2, 3, 1, 4, 5])
y = array(['f','o','o','b','a','r'])
output = y[x > 1 & x < 5] # desired output is ['o','o','a']

लेकिन यह काम नहीं करता है। यह मैं कैसे करूंगा?

जवाबों:


220

यदि आप कोष्ठक जोड़ते हैं तो आपकी अभिव्यक्ति काम करती है:

>>> y[(1 < x) & (x < 5)]
array(['o', 'o', 'a'], 
      dtype='|S1')

1
यह अच्छा है .. vecMask = 1 <x, vecMask = (असत्य, सत्य, ...) की तरह एक वेक्टर मुखौटा उत्पन्न करता है, जिसे अन्य वेक्टर मास्क के साथ जोड़ा जा सकता है। प्रत्येक तत्व एक स्रोत वेक्टर (ट्रू) या नहीं (गलत) के तत्वों को लेने के लिए शर्त है। इसका उपयोग पूर्ण संस्करण numpy.extract (vecMask, vecSrc), या numpy.where (vecMask, vecSrc, vecSrc2) के साथ भी किया जा सकता है।
मास्टरकंट्रोलोग्राम

6
@ जेनीयुजीन: यह पूर्वता के कारण होता है। (बिटवाइज़) &की तुलना में उच्च पूर्वता है <और >, जिसके बदले (तार्किक) की तुलना में उच्च पूर्वता है andx > 1 and x < 5पहले असमानताओं को और फिर तार्किक संयोजन को विकसित करता है; (और मूल्यों में) x > 1 & x < 5के समरूप संयोजन का मूल्यांकन करता है , फिर असमानताओं का। असमानताओं को पहले मूल्यांकन करने के लिए मजबूर करता है, इसलिए सभी ऑपरेशन इच्छित क्रम में होते हैं और परिणाम सभी अच्छी तरह से परिभाषित होते हैं। यहां डॉक्स देखें। 1x(x > 1) & (x < 5)
कैलाविसी

@ ru111 यह पायथन 3.6 पर भी काम करता है (इसके काम करने को रोकने का कोई कारण नहीं है)।
jfs

मुझे "ValueError: एक से अधिक तत्वों के साथ एक सरणी का सत्य मान अस्पष्ट है। a.any () या a.all ()"
ru111

@ ru111 आपको (0 < x) & (x < 10)(जैसा कि उत्तर में दिखाया गया है) लिखना चाहिए, इसके बजाय 0 < x < 10किसी भी पायथन संस्करण पर संख्यात्मक सरणियों के लिए काम नहीं करता है।
jfs

34

आईएमओ ओपी वास्तव में np.bitwise_and()(उर्फ &) नहीं चाहता है, लेकिन वास्तव में चाहता है np.logical_and()क्योंकि वे तार्किक मूल्यों की तुलना कर रहे हैं जैसे Trueऔर False- इस एसओ पोस्ट को तार्किक बनाम बिटवाइज में अंतर देखने के लिए देखें।

>>> x = array([5, 2, 3, 1, 4, 5])
>>> y = array(['f','o','o','b','a','r'])
>>> output = y[np.logical_and(x > 1, x < 5)] # desired output is ['o','o','a']
>>> output
array(['o', 'o', 'a'],
      dtype='|S1')

और ऐसा करने के लिए समतुल्य तरीका उचित रूप np.all()से axisतर्क को स्थापित करने के साथ है ।

>>> output = y[np.all([x > 1, x < 5], axis=0)] # desired output is ['o','o','a']
>>> output
array(['o', 'o', 'a'],
      dtype='|S1')

संख्याओं द्वारा:

>>> %timeit (a < b) & (b < c)
The slowest run took 32.97 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 1.15 µs per loop

>>> %timeit np.logical_and(a < b, b < c)
The slowest run took 32.59 times longer than the fastest. This could mean that an intermediate result is being cached.
1000000 loops, best of 3: 1.17 µs per loop

>>> %timeit np.all([a < b, b < c], 0)
The slowest run took 67.47 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 5.06 µs per loop

इसलिए का उपयोग कर np.all()धीमी है, लेकिन &और logical_andएक ही के बारे में कर रहे हैं।


7
आपको इस बारे में थोड़ा सावधान रहने की आवश्यकता है कि आप कैसे मूल्यांकन करते हैं, इसके बारे में बोलते हैं। उदाहरण के लिए, में output = y[np.logical_and(x > 1, x < 5)], x < 5 है का मूल्यांकन (संभवतः एक विशाल सरणी बनाने), भले ही यह दूसरा तर्क है, क्योंकि है कि मूल्यांकन कार्य के बाहर होता है। IOW, logical_andपहले से ही मूल्यांकन किए गए दो तर्कों को पारित करता है। यह सामान्य मामले से अलग है a and b, जिसमें bमूल्यांकन नहीं किया जाता है यदि aट्रुलाइक है।
DSM

15
बूलियन सरणियों के लिए बिटवाइंड_एंड () और लॉजिकल_एंड () के बीच कोई अंतर नहीं है
jfs

21

@JF सेबेस्टियन और @ मर्क मिकोफ़्स्की के उत्तरों में एक विवरण जोड़ें:
यदि कोई संबंधित सूचकांक प्राप्त करना चाहता है (बजाय सरणी के वास्तविक मूल्यों के), तो निम्न कोड करेगा:

कई (सभी) शर्तों को पूरा करने के लिए:

select_indices = np.where( np.logical_and( x > 1, x < 5) )[0] #   1 < x <5

कई (या) शर्तों को पूरा करने के लिए:

select_indices = np.where( np.logical_or( x < 1, x > 5 ) )[0] # x <1 or x >5

2
ध्यान दें कि numpy.where सिर्फ सूचकांकों की एक सरणी नहीं लौटाएगा, बल्कि इस मामले में एक tuple (condition.nonzero () के आउटपुट युक्त सरणियाँ) लौटाएगा - (the array of indices you want,)इसलिए, आपको select_indices = np.where(...)[0]वह परिणाम प्राप्त करने की आवश्यकता होगी जो आप चाहते हैं और उम्मीद है।
कैलावीसी

5

मुझे np.vectorizeऐसे कार्यों के लिए उपयोग करना पसंद है। निम्नलिखित को धयान मे रखते हुए:

>>> # Arrays
>>> x = np.array([5, 2, 3, 1, 4, 5])
>>> y = np.array(['f','o','o','b','a','r'])

>>> # Function containing the constraints
>>> func = np.vectorize(lambda t: t>1 and t<5)

>>> # Call function on x
>>> y[func(x)]
>>> array(['o', 'o', 'a'], dtype='<U1')

लाभ यह है कि आप वेक्टरकृत फ़ंक्शन में कई और प्रकार की बाधाओं को जोड़ सकते हैं।

आशा करता हूँ की ये काम करेगा।


1
यह NumPy में अनुक्रमण करने का एक अच्छा तरीका नहीं है (यह बहुत धीमा होगा)।
एलेक्स रिले

1

वास्तव में मैं इसे इस तरह से करूंगा:

L1 शर्त 1 को संतुष्ट करने वाले तत्वों की सूची है; (शायद आप L1 का उपयोग कर सकते हैं somelist.index(condition1)या np.where(condition1)प्राप्त कर सकते हैं ।)

इसी तरह, आपको एल 2 मिलता है, तत्वों की एक सूची संतोषजनक स्थिति 2;

तो आप का उपयोग कर चौराहे पाते हैं intersect(L1,L2)

यदि आपको संतुष्ट करने के लिए कई शर्तें मिलती हैं, तो आप कई सूचियों का प्रतिच्छेदन भी पा सकते हैं।

फिर आप किसी अन्य सरणी में सूचकांक लागू कर सकते हैं, उदाहरण के लिए, एक्स।


0

2D सरणियों के लिए, आप ऐसा कर सकते हैं। स्थिति का उपयोग करके 2 डी मास्क बनाएं। सरणी पर निर्भर करता है, और मूल सरणी के साथ गुणा करने के लिए स्थिति मुखौटा टाइप या फ्लोट करने के लिए टाइप करें।

In [8]: arr
Out[8]: 
array([[ 1.,  2.,  3.,  4.,  5.],
       [ 6.,  7.,  8.,  9., 10.]])

In [9]: arr*(arr % 2 == 0).astype(np.int) 
Out[9]: 
array([[ 0.,  2.,  0.,  4.,  0.],
       [ 6.,  0.,  8.,  0., 10.]])
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.