दो से अधिक तर्कों के लिए Numpy `तार्किक_ओर`


90

Numpy का logical_orफ़ंक्शन तुलना करने के लिए दो से अधिक सरणियों को नहीं लेता है। मैं दो से अधिक सरणियों का मिलन कैसे कर सकता हूं? (यही सवाल नेम्पी के संबंध logical_andमें और दो से अधिक सरणियों के प्रतिच्छेदन को प्राप्त करने के संबंध में पूछा जा सकता है ।)



वहाँ किसी भी () के लिए एक रास्ता है?
1930 बजे user3074893

@ user3074893: यह वास्तव में एक ही मुद्दा है। आप चाहते हैं कि मैं अपने उत्तर का विस्तार करूं?
19

जवाबों:


180

यदि आप के बारे में पूछ रहे हैं numpy.logical_or, तो नहीं, जैसा कि डॉक्स स्पष्ट रूप से कहते हैं, एकमात्र पैरामीटर हैं x1, x2, और वैकल्पिक रूप से out:

numpy.logical_or( x1, x2[, out]) =<ufunc 'logical_or'>


आप logical_orइस तरह से कई कॉल को एक साथ कर सकते हैं :

>>> x = np.array([True, True, False, False])
>>> y = np.array([True, False, True, False])
>>> z = np.array([False, False, False, False])
>>> np.logical_or(np.logical_or(x, y), z)
array([ True,  True,  True,  False], dtype=bool)

NumPy में इस तरह की चेनिंग को सामान्य करने का तरीका reduceनिम्न है:

>>> np.logical_or.reduce((x, y, z))
array([ True,  True,  True,  False], dtype=bool)

और निश्चित रूप से यह भी काम करेगा यदि आपके पास अलग-अलग सरणियों के बजाय एक बहु-आयामी सरणी है - वास्तव में, इसका मतलब यह है:

>>> xyz = np.array((x, y, z))
>>> xyz
array([[ True,  True, False, False],
       [ True, False,  True, False],
       [False, False, False, False]], dtype=bool)
>>> np.logical_or.reduce(xyz)
array([ True,  True,  True,  False], dtype=bool)

लेकिन तीन समान लंबाई वाले 1D सरणियों का एक टप्पर NumPy शब्दों में एक array_like है, और इसे 2D सरणी के रूप में उपयोग किया जा सकता है।


न्यूमपी के बाहर, आप पायथन का उपयोग भी कर सकते हैं reduce:

>>> functools.reduce(np.logical_or, (x, y, z))
array([ True,  True,  True,  False], dtype=bool)

हालांकि, NumPy के विपरीत reduce, पायथन की अक्सर जरूरत नहीं होती है। अधिकांश मामलों के लिए, चीजों को करने का एक सरल तरीका है - जैसे, कई पायथन orऑपरेटरों को एक साथ चेन करने के लिए, reduceखत्म न करें operator.or_, बस उपयोग करें any। और जब वहाँ नहीं है , यह आमतौर पर एक स्पष्ट लूप का उपयोग करने के लिए अधिक पठनीय है।

और वास्तव में NumPy का anyउपयोग इस मामले के लिए भी किया जा सकता है, हालांकि यह काफी तुच्छ नहीं है; यदि आप स्पष्ट रूप से इसे एक अक्ष नहीं देते हैं, तो आप एक सरणी के बजाय एक स्केलर के साथ समाप्त करेंगे। इसलिए:

>>> np.any((x, y, z), axis=0)
array([ True,  True,  True,  False], dtype=bool)

जैसा कि आप उम्मीद कर सकते हैं, logical_andयह समान है - आप इसे स्पष्ट कर सकते हैं, np.reduceइसे, functools.reduceइसे, या विकल्प के allसाथ चेन कर सकते हैं axis

अन्य कार्यों के बारे में क्या, जैसे logical_xor? फिर से, एक ही सौदा ... सिवाय इसके कि इस मामले में कोई all/ any-प्रकार फ़ंक्शन लागू नहीं होता है। (इसे आप क्या कहेंगे odd?)


3
np.logical_or.reduce((x, y, z))बस मैं क्या देख रहा था!
ब्लेकब्लॉक

reduceअजगर में अब कोई आंतरिक कार्य नहीं है। इसके बजाय उपयोग करें:functools.reduce()
मार्विन

10

कहते हैं आप तीन बूलियन सरणियों है - मामले में किसी को अभी भी इस की जरूरत है a, b, cएक ही आकार के साथ, इस देता है and: तत्व के लिहाज से

a * b * c

यह देता है or:

a + b + c

क्या ये वही है जो तुम चाहते हो? का एक बहुत स्टैकिंग logical_andया logical_orव्यावहारिक नहीं है।


6

जैसा कि बूलियन बीजगणित परिभाषा के अनुसार कम्यूटेटिव और साहचर्य दोनों हैं , क, ख और ग के बूलियन मूल्यों के लिए निम्न कथन या समकक्ष ।

a or b or c

(a or b) or c

a or (b or c)

(b or a) or c

इसलिए यदि आपके पास "लॉजिकल_ओर" है जो कि रंगादिक है और आपको इसे तीन तर्क (ए, बी, और सी) पास करने की आवश्यकता है, तो आप कॉल कर सकते हैं

logical_or(logical_or(a, b), c)

logical_or(a, logical_or(b, c))

logical_or(c, logical_or(b, a))

या आपको जो भी परमिशन चाहिए।


अजगर पर वापस जाएं, यदि आप यह परीक्षण करना चाहते हैं कि क्या एक शर्त (एक फ़ंक्शन द्वारा प्राप्त की गई है testजो एक टेस्टी लेता है और एक बूलियन मूल्य देता है) एक या बी या सी या सूची एल के किसी भी तत्व पर लागू होता है, तो आप सामान्य रूप से उपयोग करते हैं

any(test(x) for x in L)

लेकिन पायथन orवास्तव में बूलियन नहीं है or, दोनों क्योंकि यह boolएस के अलावा अन्य मूल्यों पर काम करता है ( aयदि aसत्य है, bअन्यथा) लौटना , और क्योंकि यह शॉर्ट-सर्किट है (मतलब a or bयह सच हो सकता है, जबकि b or aएक अपवाद उठाता है)।
अपराह्न

@abarnert धन्यवाद, मैंने अपना उत्तर उस हिसाब से संपादित किया है।
हाइपरबोरस

(मुझे यकीन नहीं है कि लोगों ने इसे क्यों उतारा, हालांकि ... ओपी विशेष रूप से बूलियन मूल्यों के बारे में बात कर रहा है, जिसे वह "तार्किक स्थिति" कहते हैं।)
गर्भपात

@abarnert मुझसे मत पूछो। मेरी राय है कि यदि आप पृष्ठभूमि में सीधे अपने गणित को प्राप्त करते हैं (इस मामले में बूलियन बीजगणित), तो बहुत सारे प्रोग्रामिंग मुद्दों को हल करना आसान है।
हाइपरबोरस

5

N- आयामी मामले के लिए अबर्नर्ट के उत्तर पर निर्माण:

टी एल; डॉ: np.logical_or.reduce(np.array(list))


4

राशि समारोह का उपयोग:

a = np.array([True, False, True])
b = array([ False, False,  True])
c = np.vstack([a,b,b])

Out[172]: 
array([[ True, False,  True],
   [False, False,  True],
   [False, False,  True]], dtype=bool)

np.sum(c,axis=0)>0
Out[173]: array([ True, False,  True], dtype=bool)

4

मैं इस समाधान का उपयोग करता हूं जिसे n सरणियों तक बढ़ाया जा सकता है:

>>> a = np.array([False, True, False, False])
>>> b = np.array([True, False, False, False])
>>> c = np.array([False, False, False, True])
>>> d = (a + b + c > 0) # That's an "or" between multiple arrays
>>> d
array([ True,  True, False,  True], dtype=bool)

2

मैंने निम्नलिखित तीन अलग-अलग तरीकों की कोशिश की है कि आकार n के k सरणियों की logical_andसूची l प्राप्त करने के लिए :

  1. एक पुनरावर्ती का उपयोग करना numpy.logical_and(नीचे देखें)
  2. का उपयोग करते हुए numpy.logical_and.reduce(l)
  3. का उपयोग करते हुए numpy.vstack(l).all(axis=0)

फिर मैंने logical_orफंक्शन के लिए भी ऐसा ही किया । आश्चर्यजनक रूप से पर्याप्त, पुनरावर्ती विधि सबसे तेज है।

import numpy
import perfplot

def and_recursive(*l):
    if len(l) == 1:
        return l[0].astype(bool)
    elif len(l) == 2:
        return numpy.logical_and(l[0],l[1])
    elif len(l) > 2:
        return and_recursive(and_recursive(*l[:2]),and_recursive(*l[2:]))

def or_recursive(*l):
    if len(l) == 1:
        return l[0].astype(bool)
    elif len(l) == 2:
        return numpy.logical_or(l[0],l[1])
    elif len(l) > 2:
        return or_recursive(or_recursive(*l[:2]),or_recursive(*l[2:]))

def and_reduce(*l):
    return numpy.logical_and.reduce(l)

def or_reduce(*l):
    return numpy.logical_or.reduce(l)

def and_stack(*l):
    return numpy.vstack(l).all(axis=0)

def or_stack(*l):
    return numpy.vstack(l).any(axis=0)

k = 10 # number of arrays to be combined

perfplot.plot(
    setup=lambda n: [numpy.random.choice(a=[False, True], size=n) for j in range(k)],
    kernels=[
        lambda l: and_recursive(*l),
        lambda l: and_reduce(*l),
        lambda l: and_stack(*l),
        lambda l: or_recursive(*l),
        lambda l: or_reduce(*l),
        lambda l: or_stack(*l),
    ],
    labels = ['and_recursive', 'and_reduce', 'and_stack', 'or_recursive', 'or_reduce', 'or_stack'],
    n_range=[2 ** j for j in range(20)],
    logx=True,
    logy=True,
    xlabel="len(a)",
    equality_check=None
)

यहाँ k = 4 के प्रदर्शन के नीचे।

के = 4 के लिए प्रदर्शन

और यहाँ k = 10 के प्रदर्शन के नीचे।

के = 10 के लिए प्रदर्शन

ऐसा लगता है कि उच्च n के लिए भी लगभग निरंतर समय ओवरहेड है।

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