Numpy的logical_or
函数只需要两个数组比较即可。如何找到两个以上数组的并集?(关于Numpy'slogical_and
并获得两个以上数组的交集,可能会问相同的问题。)
Numpy的logical_or
函数只需要两个数组比较即可。如何找到两个以上数组的并集?(关于Numpy'slogical_and
并获得两个以上数组的交集,可能会问相同的问题。)
Answers:
如果您询问的是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_,并且可以用作2D数组。
在NumPy之外,您还可以使用Python的reduce
:
>>> functools.reduce(np.logical_or, (x, y, z))
array([ True, True, True, False], dtype=bool)
但是,与NumPy的不同reduce
,Python并不是经常需要的。在大多数情况下,有一种更简单的方法来执行操作-例如,将多个Pythonor
运算符链接在一起,不要停下reduce
来operator.or_
,只需要使用即可any
。如果没有,使用显式循环通常更易读。
实际上,NumPyany
也可以用于这种情况,尽管它并不是那么简单。如果您未明确为其指定轴,则最终将得到标量而不是数组。所以:
>>> 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
-type函数。(你叫什么odd
??)
np.logical_or.reduce((x, y, z))
正是我想要的!
reduce
不再是python 3中的内部函数。而是使用:functools.reduce()
由于布尔代数在定义上既是可交换的又是关联的,因此对于a,b和c的布尔值,以下语句或等效语句。
a or b or c
(a or b) or c
a or (b or c)
(b or a) or c
因此,如果您有一个二元的“ logical_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)
or
并不是真正的布尔值or
,这不仅是因为它可以处理bool
s以外的值(a
如果返回a
true,b
否则返回),还因为它短路(含义a or b
可能为True,而b or a
引发异常)。
我使用可以扩展到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)
我尝试了以下三种不同的方法来获取大小为n的k个数组的logical_and
列表l的:
numpy.logical_and
(见下文)numpy.logical_and.reduce(l)
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的性能。
下面是k = 10的性能。
似乎对于较高的n也存在大约恒定的时间开销。
any()
?