Python Numpy `logical_or` 用于两个以上的参数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20528328/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 20:40:35  来源:igfitidea点击:

Numpy `logical_or` for more than two arguments

pythonarraysnumpy

提问by user3074893

Numpy's logical_orfunction takes no more than two arrays to compare. How can I find the union of more than two arrays? (The same question could be asked with regard to Numpy's logical_andand obtaining the intersection of more than two arrays.)

Numpy 的logical_or函数需要不超过两个数组进行比较。如何找到两个以上数组的并集?(关于 Numpylogical_and和获得两个以上数组的交集,可以问同样的问题。)

回答by Hyperboreus

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

由于布尔代数根据定义既可交换又可结合,因此以下语句或对 a、b 和 c 的布尔值等效的语句。

a or b or c

a or b or c

(a or b) or c

(a or b) or c

a or (b or c)

a or (b or c)

(b or a) 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”,并且需要向它传递三个参数(a、b 和 c),则可以调用

logical_or(logical_or(a, b), c)

logical_or(logical_or(a, b), c)

logical_or(a, logical_or(b, c))

logical_or(a, logical_or(b, c))

logical_or(c, logical_or(b, a))

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 testthat takes a testee and returns a boolean value) applies to a or b or c or any element of list L, you normally use

回到python,如果你想测试一个条件(由一个test接受testee并返回一个布尔值的函数产生)是否适用于a或b或c或列表L的任何元素,你通常使用

any(test(x) for x in L)

回答by abarnert

If you're asking about numpy.logical_or, then no, as the docs explicitly say, the only parameters are x1, x2, and optionally out:

如果你问的是numpy.logical_or,那么不,正如文档明确所说,唯一的参数是x1, x2, 和可选的out

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

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



You can of course chain together multiple logical_orcalls like this:

您当然可以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)


The way to generalize this kind of chaining in NumPy is with reduce:

在 NumPy 中推广这种链接的方法是reduce

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

And of course this will also work if you have one multi-dimensional array instead of separate arrays—in fact, that's how it's meantto be used:

当然这也将工作,如果你有一个多维数组,而不是单独的阵列,事实上,这就是它的意思被使用:

>>> 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)

But a tuple of three equal-length 1D arrays is an array_likein NumPy terms, and can be used as a 2D array.

但是三个等长一维数组的元组在 NumPy 术语中是一个array_like,并且可以用作二维数组。



Outside of NumPy, you can also use Python's reduce:

在 NumPy 之外,您还可以使用 Python 的reduce

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

However, unlike NumPy's reduce, Python's is not often needed. For most cases, there's a simpler way to do things—e.g., to chain together multiple Python oroperators, don't reduceover operator.or_, just use any. And when there isn't, it's usually more readable to use an explicit loop.

但是,与 NumPy 的 不同reduce,通常不需要 Python 的。在大多数情况下,有一种更简单的方法来做事——例如,将多个 Pythonor运算符链接在一起,不要reduce超过operator.or_,只需使用any. 当没有时,使用显式循环通常更具可读性。

And in fact NumPy's anycan be used for this case as well, although it's not quite as trivial; if you don't explicitly give it an axis, you'll end up with a scalar instead of an array. So:

事实上,NumPyany也可以用于这种情况,尽管它不是那么简单;如果你没有明确地给它一个轴,你最终会得到一个标量而不是一个数组。所以:

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


As you might expect, logical_andis similar—you can chain it, np.reduceit, functools.reduceit, or substitute allwith an explicit axis.

正如您所料,它logical_and是相似的——您可以将它、np.reduce它、functools.reduce它链接起来,或者all用一个显式的axis.

What about other operations, like logical_xor? Again, same deal…?except that in this case there is no all/any-type function that applies. (What would you call it? odd?)

其他操作logical_xor呢,比如?同样,同样的交易......?除了在这种情况下没有适用的all/ any-type 函数。(你会怎么称呼它odd??)

回答by citynorman

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

基于 abarnert 对 n 维案例的回答:

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

特尔;博士: np.logical_or.reduce(np.array(list))

回答by Alex

In case someone still need this - Say you have three Boolean arrays a, b, cwith the same shape, this gives andelement-wise:

如果有人仍然需要这一点-你说你有三个布尔数组abc形状相同,这给and元素方面:

a * b * c

this gives or:

这给出了or

a + b + c

Is this what you want? Stacking a lot of logical_andor logical_oris not practical.

这是你想要的吗?堆叠很多logical_and还是logical_or不实用。

回答by alexk

using the sum function:

使用 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)

回答by Giovanni Tardini

I use this workaround which can be extended to n arrays:

我使用这个可以扩展到 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)

回答by Giancarlo Sportelli

I've tried the following three different methods to get the logical_andof a list lof karrays of size n:

我尝试了以下三种不同的方法来获取大小为nk 个数组的logical_and列表l的列表:

  1. Using a recursive numpy.logical_and(see below)
  2. Using numpy.logical_and.reduce(l)
  3. Using numpy.vstack(l).all(axis=0)
  1. 使用递归numpy.logical_and(见下文)
  2. 使用 numpy.logical_and.reduce(l)
  3. 使用 numpy.vstack(l).all(axis=0)

Then I did the same for the logical_orfunction. Surprisingly enough, the recursive method is the fastest one.

然后我对这个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
)

Here below the performances for k = 4.

下面是 k = 4 的表现。

Performances for k=4

k=4 时的表现

And here below the performances for k = 10.

下面是 k = 10 的表现。

Performances for k=10

k=10 时的表现

It seems that there is an approximately constant time overhead also for higher n.

似乎对于更高的 n 也有一个近似恒定的时间开销。