Question

I have multiple matrices of 0's and 1's that I'd like to find the NOT'd versions of. For example:

M  
0 1 0  
1 0 1  
0 1 0

would become:

!M  
1 0 1  
0 1 0  
1 0 1

Right now I've got

for row in image:
    map(lambda x: 1 if x == 0 else 0, row)

which works perfectly well, but I've got a feeling that I've seen this done really simply with broadcasting. Unfortunately nothing I've looked up has rung a bell yet. I assume that a similar operation would be used for thresholding the values of a matrix (i.e. something like 1 if x > .5 else 0).

Was it helpful?

Solution

Given an integer array of 0s and 1s:

M = np.random.random_integers(0,1,(5,5))
print(M)
# [[1 0 0 1 1]
#  [0 0 1 1 0]
#  [0 1 1 0 1]
#  [1 1 1 0 1]
#  [0 1 1 0 0]]

Here are three ways you could NOT the array:

  1. Convert to a boolean array and use the ~ operator to bitwise NOT the array:

    print((~(M.astype(np.bool))).astype(M.dtype))
    # [[0 1 1 0 0]
    #  [1 1 0 0 1]
    #  [1 0 0 1 0]
    #  [0 0 0 1 0]
    #  [1 0 0 1 1]]
    
  2. Use numpy.logical_not and cast the resulting boolean array back to integers:

    print(np.logical_not(M).astype(M.dtype))
    # [[0 1 1 0 0]
    #  [1 1 0 0 1]
    #  [1 0 0 1 0]
    #  [0 0 0 1 0]
    #  [1 0 0 1 1]]
    
  3. Just subtract all your integers from 1:

    print(1 - M)
    # [[0 1 1 0 0]
    #  [1 1 0 0 1]
    #  [1 0 0 1 0]
    #  [0 0 0 1 0]
    #  [1 0 0 1 1]]
    

The third way will probably be quickest for most non-boolean dtypes.

OTHER TIPS

One solution is to convert your array to a boolean array

data = np.ones((4, 4))
bdata = np.array(data, dtype=bool)
print ~bdata
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top