I've got a 2D array comprised of boolean values (True,False). I'd like to consolidate the array to a 1D based on a logical function of the contents.
e.g. Input:
[[True, True, False],
[False, False, False],
[True, True, True]]
Output (logical AND):
[False,
False,
True]
How would this be done without a loop ?
You can use Python's built-in all
method with a list-comprehension:
[all(x) for x in my_list]
If that's still too loopy for you, combine it with map
:
map(all, my_list)
Note that map
doesn't return a list in Python 3. If you want a list as your result, you can call list(map(all, my_list))
instead.
You can do this without NumPy too. Here is one solution using list comprehension. Explanation: It will loop over sub-lists and even if one of the items in each sub-list is False
, it outputs False
else 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]
Alternative (less verbose) as suggested by Jean below:
out = [False not in i for i in inp]
I'm assuming you want to apply logical ANDs to the rows. You can apply 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])
For a solution without numpy
, you can use operator.and_
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]
edit: actually, reduce
is a bit redundant in this particular case.
>>> [all(sub) for sub in lst]
[False, False, True]
does the job just as well.
You can do this with numpy with the 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])
Here thus the i-th element is True
if all elements of the i-th row are True
, and False
otherwise. Note that the list should be rectangular (all sublists should contain the same number of booleans).
In "pure" Python, you can use the all
function as well, like:
>>> data = [[True, True, False], [False, False, False], [True, True, True]]
>>> list(map(all, data))
[False, False, True]
This approach will work as well if the "matrix" is not rectangular. Note that for an empty sublist, this will return True
, since all elements in an empty sublist are True
.
You can also do this with map
and reduce
:
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]
The benefit here is that you can change the reduce
function to something else (say, an OR or something more adventurous).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With