Вопрос-Ответ

Numpy `logical_or` for more than two arguments

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

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

Переведено автоматически
Ответ 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)

Но кортеж из трех одномерных массивов одинаковой длины является array_like в терминах NumPy и может использоваться как двумерный массив.


Помимо 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 это, functools.reduce это или заменить all явным axis.

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

Ответ 2

На случай, если кому-то это все еще нужно - скажем, у вас есть три логических массива a, b, c с одинаковой формой, это дает and поэлементный результат:

a * b * c

this gives or:

a + b + c

Is this what you want?
Stacking a lot of logical_and or logical_or is not practical.

Ответ 3

Building on abarnert's answer for n-dimensional case:

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

Ответ 4

As boolean algebras are both commutative and associative by definition, the following statements or equivalent for boolean values of a, b and c.

a or b or c

(a or b) or c

a or (b or c)

(b or a) or c

So if you have a "logical_or" which is dyadic and you need to pass it three arguments (a, b, and c), you can call

logical_or(logical_or(a, b), c)

logical_or(a, logical_or(b, c))

logical_or(c, logical_or(b, a))

or whatever permutation you like.


Back to python, if you want to test whether a condition (yielded by a function test that takes a testee and returns a boolean value) applies to a or b or c or any element of list L, you normally use

any(test(x) for x in L)
python arrays numpy