How to intersect boolean subarrays for True values? - python

I know that Numpy provides logical_and() which allows us to intersect two boolean arrays for True values only (True and True would yield True while True and False would yield False). For example,
a = np.array([True, False, False, True, False], dtype=bool)
b = np.array([False, True, True, True, False], dtype=bool)
np.logical_and(a, b)
> array([False, False, False, True, False], dtype=bool)
However, I'm wondering how I can apply this to two subarrays in an overall array? For example, consider the array:
[[[ True, True], [ True, False]], [[ True, False], [False, True]]]
The two subarrays I'm looking to intersect are:
[[ True, True], [ True, False]]
and
[[ True, False], [False, True]]
which should yield:
[[ True, False], [False, False]]
Is there a way to specify that I want to apply logical_and() to the outermost subarrays to combine the two?

You can use .reduce() along the first axis:
>>> a = np.array([[[ True, True], [ True, False]], [[ True, False], [False, True]]])
>>> np.logical_and.reduce(a, axis=0)
array([[ True, False],
[False, False]])
This works even when you have more than two "sub-arrays" in your outer array. I prefer this over the unpacking approach because it allows you to apply your function (np.logical_and) over any axis of your array.

If I understand your question correctly, you are looking to do:
import numpy as np
output = np.logical_and(a[:, 0], a[:, 1])
This simply slices your arrays so that you can use logical_and the way your results suggest.

Related

How do I combine multiple NumPy boolean arrays?

I have a two-dimensional (2D) array that contains many one-dimensional (1D) arrays of random boolean values.
import numpy as np
def random_array_of_bools():
return np.random.choice(a=[False, True], size=5)
boolean_arrays = np.array([
random_array_of_bools(),
random_array_of_bools(),
... so on
])
Assume that I have three arrays:
[True, False, True, True, False]
[False, True, True, True, True]
[True, True, True, False, False]
This is my desired result:
[False, False, True, False, False]
How can I achieve this with NumPy?
Use min with axis=0:
>>> boolean_array.min(axis=0)
array([False, False, True, False, False])
>>>
Use .all:
import numpy as np
arr = np.array([[True, False, True, True, False],
[False, True, True, True, True],
[True, True, True, False, False]])
res = arr.all(0)
print(res)
Output
[False False True False False]
try numpy bitwise_and =>
out_arr = np.bitwise_and(np.bitwise_and(in_arr1, in_arr2),in_arr3)

Combine mask across all channels

I have some condition tested in all 3 channels of an image, so I have something like:
import numpy as np
check = np.array([[[True, True], [True, False]], [[True, False], [False, False]], [[True, True], [True, True]]])
where dimensions are: channel (RGB), height, width.
I want to get 2D array, that shows that all corresponding pixels of different channels are true, so I want to get
result = np.array([[True, False], [False, False]])
Currently, I'm doing it this ways:
result = np.logical_and(check[0, :, :], check[1, :, :], check[2, :, :])
But I'm sure there is a more elegant way to do this
You can use numpy.all along the axis of interest:
import numpy as np
check = np.array([[[True, True],
[True, False]],
[[True, False],
[False, False]],
[[True, True],
[True, True]]])
np.all(check, axis=0)
array([[ True, False],
[False, False]])
Alternatively you can use a list comprehension on check just because you are comparing along the first axis:
np.logical_and(*[c for c in check])
array([[ True, False],
[False, False]])

How to change the values of a 2d tensor in certain rows and columns

Suppose I have an all-zero mask tensor like this:
mask = torch.zeros(5,3, dtype=torch.bool)
Now I want to set the value of mask at the intersection of the following rows and cols indices to True:
rows = torch.tensor([0,2,4])
cols = torch.tensor([1,2])
I would like to produce the following result:
tensor([[False, True, True ],
[False, False, False],
[False, True, True ],
[False, False, False],
[False, True, True ]])
When I try the following code, I receive an error:
mask[rows, cols] = True
IndexError: shape mismatch: indexing tensors could not be broadcast together with shapes [3], [2]
How can I do that efficiently in PyTorch?
You need proper shape for that you can use torch.unsqueeze
mask = torch.zeros(5,3, dtype=torch.bool)
mask[rows, cols.unsqueeze(1)] = True
mask
tensor([[False, True, True],
[False, False, False],
[False, True, True],
[False, False, False],
[False, True, True]])
or torch.reshape
mask[rows, cols.reshape(-1,1)] = True
mask
tensor([[False, True, True],
[False, False, False],
[False, True, True],
[False, False, False],
[False, True, True]])

Compare a numpy array to each element of another one

A = np.array([5,1,5,8])
B = np.array([2,5])
I want to compare the A array to each element of B. In other words I'm lookin for a function which do the following computations :
A>2
A>5
(array([ True, False, True, True]), array([False, False, False, True]))
Not particularly fancy but a list comprehension will work:
[A > b for b in B]
[array([ True, False, True, True], dtype=bool),
array([False, False, False, True], dtype=bool)]
You can also use np.greater(), which requires the dimension-adding trick that Brenlla uses in the comments:
np.greater(A, B[:,np.newaxis])
array([[ True, False, True, True],
[False, False, False, True]], dtype=bool)

Intersect two boolean arrays for True

Having the numpy arrays
a = np.array([ True, False, False, True, False], dtype=bool)
b = np.array([False, True, True, True, False], dtype=bool)
how can I make the intersection of the two so that only the True values match? I can do something like:
a == b
array([False, False, False, True, True], dtype=bool)
but the last item is True (understandably because both are False), whereas I would like the result array to be True only in the 4th element, something like:
array([False, False, False, True, False], dtype=bool)
Numpy provides logical_and() for that purpose:
a = np.array([ True, False, False, True, False], dtype=bool)
b = np.array([False, True, True, True, False], dtype=bool)
c = np.logical_and(a, b)
# array([False, False, False, True, False], dtype=bool)
More at Numpy Logical operations.

Categories