Python 2d 数组布尔减少

Posted

技术标签:

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

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

例如 输入:

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

输出(逻辑与):

[False,
 False,
 True]

没有循环怎么办?

【问题讨论】:

为什么没有循环?循环用于迭代可变长度的可迭代对象,因此如果您在没有循环的情况下执行此操作,您将失去“可变长度”的好处(并且必须对索引进行硬编码)。还是您只是在采用一种对您隐藏循环的方法? 【参考方案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 和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 或更冒险的内容)。

【讨论】:

以上是关于Python 2d 数组布尔减少的主要内容,如果未能解决你的问题,请参考以下文章

使用两个布尔数组索引 2D np.array 时的意外行为

在 numpy 中从具有索引的 2D 矩阵构建 3D 布尔矩阵

从 Java 中的二进制图像(布尔数组)裁剪

如何在Java中将二维布尔数组转换为一维字节数组?

如何在 Python 中切换布尔数组?

Python 只有整数、切片...和整数或布尔数组是有效的索引