Подтвердить что ты не робот

Numpy `logical_or` для более чем двух аргументов

Функция Numpy logical_or позволяет сравнивать не более двух массивов. Как я могу найти объединение более чем двух массивов? (Тот же вопрос можно задать в отношении Numpy logical_and и получить пересечение более двух массивов.)

4b9b3361

Ответ 1

Если вы спрашиваете о 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 представляет собой array_like в терминах NumPy и может использоваться как 2D-массив.


Вне NumPy вы также можете использовать Python reduce:

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

Однако, в отличие от NumPy reduce, Python часто не нужен. В большинстве случаев существует более простой способ сделать что-то, например, для объединения нескольких операторов Python 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 it, functools.reduce it, или замените all с явным axis.

Как насчет других операций, таких как logical_xor? Опять же, такая же сделка... за исключением того, что в этом случае нет функции all/any -type, которая применяется. (Как бы вы это назвали? odd?)

Ответ 2

Так как булевы алгебры являются как коммутативными, так и ассоциативными по определению, следующие утверждения или эквиваленты для значений boolean a, b и c.

a or b or c

(a or b) or c

a or (b or c)

(b or a) or c

Итак, если у вас есть "логический_or", который является двоичным, и вам нужно передать ему три аргумента (a, b и c), вы можете вызвать

logical_or(logical_or(a, b), c)

logical_or(a, logical_or(b, c))

logical_or(c, logical_or(b, a))

или любую перестановку, которая вам нравится.


Вернемся к python, если вы хотите проверить, является ли условие (полученное функцией test, которая принимает тестируемого и возвращает логическое значение) применяется к a или b или c или к любому элементу списка L, вы обычно используете

any(test(x) for x in L)

Ответ 3

В случае, если кому-то все еще нужно это - Скажем, у вас есть три булевых массива a, b, c с одинаковой формой, это дает and element-wise:

a * b * c

это дает or:

a + b + c

Это то, что вы хотите? Укладка большого количества logical_and или logical_or непрактична.

Ответ 4

с использованием функции sum:

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)

Ответ 5

Построение ответа abarnert для n-мерного случая:

TL; DR: np.logical_or.reduce(np.array(list))