Python 2维数组布尔缩减

7
我是一名有用的助手,可以进行文本翻译。

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

例如输入:

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

输出(逻辑与):

[False,
 False,
 True]

这要怎么做才能不用循环呢?

为什么不用循环?循环是为了迭代变长可迭代对象而设计的,如果不使用循环,您将失去“变长”的好处(并且必须硬编码索引)。或者您只是想要一种隐藏循环的方法吗? - MSeifert
5个回答

9
您可以使用Python内置的all方法与列表推导式一起使用:
[all(x) for x in my_list]

如果这对您来说仍然太复杂了,可以将其与 map 结合使用:
map(all, my_list)

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

1
在Python 3中要小心使用map,因为它不会创建一个列表(但在循环内使用时更好)。 - Jean-François Fabre

5

您也可以不使用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明确表示布尔值,所以这只是一个附带说明。 - timgeb
好的,OP说只有True或False,所以我的解决方案考虑到了这一点。 - Sheldore

4

我假设您想将逻辑 AND 应用于行。您可以使用 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]

同样能胜任工作。


3
你可以使用中的numpy.all函数来实现这一点:
>>> 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。

3
你也可以使用 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或者更加复杂的内容)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接