【问题标题】:Python 2d array boolean reductionPython 2d 数组布尔减少
【发布时间】:2019-03-20 07:05:38
【问题描述】:

我有一个由布尔值(真、假)组成的二维数组。我想根据内容的逻辑函数将数组合并为一维。

例如 输入:

[[True, True, False],
 [False, False, False],
 [True, True, True]]

输出(逻辑与):

[False,
 False,
 True]

没有循环怎么办?

【问题讨论】:

  • 为什么没有循环?循环用于迭代可变长度的可迭代对象,因此如果您在没有循环的情况下执行此操作,您将失去“可变长度”的好处(并且必须对索引进行硬编码)。还是您只是在采用一种对您隐藏循环的方法?

标签: python arrays reduction


【解决方案1】:

您可以将 Python 的内置 all 方法与列表理解一起使用:

[all(x) for x in my_list]

如果这对您来说仍然太循环,请将其与 map 结合使用:

map(all, my_list)

请注意,map 在 Python 3 中不会返回列表。如果您想要一个列表作为结果,您可以调用 list(map(all, my_list))

【讨论】:

  • 在 python 3 中小心map,因为它不会创建列表(但在循环中使用时会更好)
【解决方案2】:

你也可以在没有 NumPy 的情况下做到这一点。这是使用列表理解的一种解决方案。解释:它将遍历子列表,即使每个子列表中的一项是False,它也会输出False,否则输出True

inp = [[True, True, False],[False, False, False],[True, True, True]]
out = [False if False in i else True for i in inp]
print (out)

# [False, False, True]

下面 Jean 建议的替代方案(不那么冗长):

out = [False not in i for i in inp]

【讨论】:

  • 当您在子列表中可以有其他虚假值(例如0)时,这很聪明,但并不完全等同于每个子列表的x1 and x2 and ... xn。当然,OP 明确表示布尔值,所以这只是一个旁注。
  • 好吧,OP 说只有真或假,所以我的解决方案解决了这个问题
【解决方案3】:

我假设您想对行应用逻辑与。你可以申请numpy.all

>>> import numpy as np
>>> a = np.array([[True, True, False], [False, False, False], [True, True, True]])
>>> a
array([[ True,  True, False],
       [False, False, False],
       [ True,  True,  True]])
>>> 
>>> np.all(a, axis=1)
array([False, False,  True])

对于没有numpy 的解决方案,您可以使用operator.and_functools.reduce

>>> from operator import and_
>>> from functools import reduce
>>> 
>>> lst = [[True, True, False], [False, False, False], [True, True, True]]
>>> [reduce(and_, sub) for sub in lst]
[False, False, True]

编辑:实际上,reduce 在这种特殊情况下有点多余。

>>> [all(sub) for sub in lst]
[False, False, True]

也能胜任这项工作。

【讨论】:

    【解决方案4】:

    您可以通过numpy.all function 来做到这一点:

    >>> import numpy as np
    >>> arr = np.array([[True, True, False],
    ... [False, False, False],
    ... [True, True, True]]
    ... )
    >>> np.all(arr, axis=1)
    array([False, False,  True])
    

    因此,如果第 i 行的 所有 元素都是 True,那么第 i 元素是 True,并且False 否则。请注意,列表应该是矩形(所有子列表应该包含相同个布尔值)。

    在“纯”Python 中,您也可以使用 all 函数,例如:

    >>> data = [[True, True, False], [False, False, False], [True, True, True]]
    >>> list(map(all, data))
    [False, False, True]
    

    如果“矩阵”不是矩形,这种方法也可以。请注意,对于 子列表,这将返回 True,因为空子列表中的 所有 元素都是 True

    【讨论】:

      【解决方案5】:

      您也可以使用mapreduce 执行此操作:

      from functools import reduce
      
      l = [[True, True, False],
          [False, False, False],
          [True, True, True]]
      
      final = list(map(lambda x: reduce(lambda a, b: a and b, x), l))
      print(final)
      # [False, False, True]
      

      这里的好处是您可以将reduce 函数更改为其他内容(例如,OR 或更冒险的内容)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-12
        • 2012-03-17
        • 1970-01-01
        • 2021-09-17
        • 2013-10-20
        • 1970-01-01
        相关资源
        最近更新 更多