Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Elementwise AND or OR operations in python for 2D array

Is there any method in python to compute elementwise OR or AND operations for 2D arrays across rows or columns?

For example, for the following array, elementwise OR operations across row would result in a vector [1, 0, 0, 0, 0, 0, 0, 0].

array([[1, 0, 0, 0, 0, 0, 0, 0],
       [1, 0, 0, 0, 0, 0, 0, 0],
       [1, 0, 0, 0, 0, 0, 0, 0],
       [1, 0, 0, 0, 0, 0, 0, 0]], dtype=uint8)
like image 691
thetna Avatar asked Oct 28 '25 20:10

thetna


1 Answers

numpy has logical_or, logical_xor and logical_and which have a reduce method

>> np.logical_or.reduce(a, axis=0)
array([ True, False, False, False, False, False, False, False], dtype=bool)

as you see in the example they coerce to bool dtype, so if you require uint8 you have to cast back in the end.

since bools are stored as bytes you can use cheap viewcasting for that.

with the axis keyword you can select along which axis to reduce. it is possible to select multiple axes

>> np.logical_or.reduce(a, axis=1)
array([ True,  True,  True,  True], dtype=bool)
>>> np.logical_or.reduce(a, axis=(0, 1))
True

the keepdims keyword is useful for broadcasting, for example to find all "crosses" of rows and columns >= 2 in array b

>>> b = np.random.randint(0,10, (4, 4))
>>> b
array([[0, 5, 3, 4],
       [4, 1, 5, 4],
       [4, 5, 5, 5],
       [2, 4, 6, 1]])
>>> rows = np.logical_and.reduce(b >= 2, axis=1, keepdims=True)
# keepdims=False (default) -> rows.shape==(4,)  keepdims=True -> rows.shape==(4, 1)
>>> cols = np.logical_and.reduce(b >= 2, axis=0, keepdims=True)
# keepdims=False (default) -> cols.shape==(4,)  keepdims=True -> cols.shape==(1, 4)
>>> rows & cols # shapes (4, 1) and (1, 4) are broadcast to (4, 4)
array([[False, False, False, False],
       [False, False, False, False],
       [False, False,  True, False],
       [False, False, False, False]], dtype=bool)

notice the slight abuse of the & operator which stands for bitwise_and. since the effect is the same on bools (in fact trying to use and in this place would have thrown an exception) this is common practice

as @ajcr points out the popular np.any and np.all are shorthand for np.logical_or.reduce and np.logical_and.reduce. note, however, that there are subtle differences

>>> np.logical_or.reduce(a)
array([ True, False, False, False, False, False, False, False], dtype=bool)
>>> np.any(a)
True

OR:

if you want to stick with uint8 and know for certain all your entries will be 0 and 1 you can use bitwise_and, bitwise_or and bitwise_xor

>>> np.bitwise_or.reduce(a, axis=0)
array([1, 0, 0, 0, 0, 0, 0, 0], dtype=uint8)
like image 50
Paul Panzer Avatar answered Oct 31 '25 12:10

Paul Panzer