So, this is something, that should be pretty easy, but it seems to take an enormous amount of time for me: I have a numpy array with only two values (example 0 and 255) and I want to invert the matrix in that way, that all values swap (0 becomes 255 and vice versa). The matrices are about 2000³ entries big, so this is serious work! I first tried the numpy.invert method, which is not exactly what I expected. So I tried to do that myself by "storing" the values and then override them:
for i in range(array.length):
array[i][array[i]==255]=1
array[i][array[i]==0]=255
array[i][array[i]==1]=0
which is behaving as expected, but taking a long time (I guess due to the for loop?). Would that be faster if I implement that as a multithreaded calculation, where every thread "inverts" a smaller sub-array? Or is there another way of doing that more conveniently?
In addition to @JanneKarila's and @EOL's excellent suggestions, it's worthwhile to show a more efficient approach to using a mask to do the swap.
Using a boolean mask is more generally useful if you have a more complex comparison than simply swapping two values, but your example uses it in a sub-optimal way.
Currently, you're making multiple temporary copies of the boolean "mask" array (e.g. array[i] == blah) in your example above and performing multiple assignments. You can avoid this by just making the "mask" boolean array once and the inverting it.
If you have enough ram for a temporary copy (of bool dtype), try something like this:
mask = (data == 255)
data[mask] = 0
data[~mask] = 255
Alternately (and equivalently) you could use numpy.where:
data = numpy.where(data == 255, 0, 255)
If you were using a loop to avoid making a full temporary copy, and need to conserve ram, adjust your loop to be something more like this:
for i in range(len(array)):
mask = (array[i] == 255)
array[mask] = 0
array[~mask] = 255
All that having been said, either subtraction or XOR is the way to go in this case, especially if you preform the operation in-place!
To swap 0 and 255, you can use XOR if the data type is one of the integer types.
array ^= 255
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