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

2024-12-16 08:35:00
admin
原创
156
摘要:问题描述:Numpy 的logical_or函数最多只接受两个数组进行比较。如何找到两个以上数组的并集?(关于 Numpylogical_and和获取两个以上数组的交集,可以提出同样的问题。)解决方案 1:如果你问的是numpy.logical_or,那么不是,正如文档明确指出的那样,唯一的参数是x1, x2...

问题描述:

Numpy 的logical_or函数最多只接受两个数组进行比较。如何找到两个以上数组的并集?(关于 Numpylogical_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)

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


除了 NumPy 之外,你还可以使用 Python 的reduce

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

但是,与 NumPy 不同reduce,Python 的 并不经常需要。在大多数情况下,有一种更简单的方法可以完成任务 — 例如,要将多个 Pythonor运算符链接在一起,不要使用reduceover 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类型函数。(你会怎么称呼它??odd

解决方案 2:

如果有人仍然需要这个 - 假设你有三个布尔数组a,,,具有相同bc形状,这给出and元素方式:

a * b * c

得出or

a + b + c

这是你想要的吗?堆叠很多logical_andlogical_or不切实际。

解决方案 3:

基于 abarnert 对 n 维情况的回答:

总结:np.logical_or.reduce(np.array(list))

解决方案 4:

由于布尔代数根据定义既是交换的又是结合的,因此以下语句或等价于布尔值 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)

解决方案 5:

我尝试了以下三种不同的方法来获取大小为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 的表现。

k=4 时的表现

下面是 k = 10 的表现。

k=10 时的性能

对于更高的 n,似乎也存在大约恒定的时间开销。

解决方案 6:

我使用这个解决方法,它可以扩展到 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)

解决方案 7:

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

解决方案 8:

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

# logical or
lor = (a+b+c+d).astype(bool)

# logical and
land = (a*b*c*d).astype(bool)

解决方案 9:

如果您想要一个简短(可能不是最佳)的函数来对多维布尔掩码执行逻辑与运算,则可以使用这个递归 lambda 函数:

masks_and = lambda *masks : masks[0] if len(masks) == 1 else masks_and(np.logical_and(masks[0], masks[-1]), *masks[1:-1])
result = masks_and(mask1, mask2, ...)

您还可以推广 lambda 函数,以将任何具有分配属性(例如乘法/AND、总和/OR 等)的运算符(2 个参数的函数)应用于任何对象,假设顺序也很重要,如下所示:

fn2args_reduce = lambda fn2args, *args : args[0] if len(args) == 1 else fn2args_reduce(fn2args, fn2args(args[0], args[1]), *args[2:])
result = fn2args_reduce(np.dot, matrix1, matrix2, ... matrixN)

其结果与使用@numpy 运算符的结果相同):

np.dot(...(np.dot(np.dot(matrix1, matrix2), matrix3)...), matrixN)

例如fn2args_reduce(lambda a,b: a+b, 1,2,3,4,5)给你 15 - 这些数字的总和(当然你有一个更高效的sum函数,但我喜欢它)。

对于 N 个参数的函数来说,更广义的模型可能如下所示:

fnNargs_reduce = lambda fnNargs, N, *args : args[0] if len(args) == 1 else fnNargs_reduce(fnNargs, N, fnNargs(*args[:N]), *args[N:])
fnNargs = lambda x1, x2, x3=neutral, ..., xN=neutral: x1 (?) x2 (?) ... (?) xN

其中,中性表示它是 (?) 运算符的中性元素,例如 + 为 0,* 为 1,等等。

为什么?只是为了好玩 :-)

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   2500  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1541  
  PLM(产品生命周期管理)项目对于企业优化产品研发流程、提升产品质量以及增强市场竞争力具有至关重要的意义。然而,在项目推进过程中,范围蔓延是一个常见且棘手的问题,它可能导致项目进度延迟、成本超支以及质量下降等一系列不良后果。因此,有效避免PLM项目范围蔓延成为项目成功的关键因素之一。以下将详细阐述三大管控策略,助力企业...
plm系统   16  
  PLM(产品生命周期管理)项目管理在企业产品研发与管理过程中扮演着至关重要的角色。随着市场竞争的加剧和产品复杂度的提升,PLM项目面临着诸多风险。准确量化风险优先级并采取有效措施应对,是确保项目成功的关键。五维评估矩阵作为一种有效的风险评估工具,能帮助项目管理者全面、系统地评估风险,为决策提供有力支持。五维评估矩阵概述...
免费plm软件   23  
  引言PLM(产品生命周期管理)开发流程对于企业产品的全生命周期管控至关重要。它涵盖了从产品概念设计到退役的各个阶段,直接影响着产品质量、开发周期以及企业的市场竞争力。在当今快速发展的科技环境下,客户对产品质量的要求日益提高,市场竞争也愈发激烈,这就使得优化PLM开发流程成为企业的必然选择。缺陷管理工具和六西格玛方法作为...
plm产品全生命周期管理   26  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用