Reputation: 401
This question sounds like it may have already been solved, but even though I looked, I couldn't find an answer.
So, I've got a NumPy
array that contains zeros in some indices:
a = np.array([[1, 2, 3], [4, 0, 0], [7, 8, 0]])
And another NumPy
array, with the same shape, that may or may not contain zeros (it usually doesn't):
b = np.array([[10, 11, 12], [13, 14, 15], [16, 17, 18]])
I need to subtract b
from a
only where a
is not zero.
So, my result should be:
array([[-9, -9, -9],
[-9, 0, 0],
[-9, -9, 0]])
Notice that because I'm not subtracting when a
is zero, the zeros stay in place.
First, I tried using a mask:
a[a!=0] = -b
But the mask, of course, only returns the elements that are not zero and all the information about the indices is lost, so this fails:
TypeError: NumPy boolean array indexing assignment requires a 0 or 1-dimensional input, input has 2 dimensions.
Then, I tried using np.subtract
with the argument where
:
subtraction = np.subtract(a, b, where=a!=0)
But it resulted in this (I assume it's because of the mask created by where
):
array([[-9, -9, -9],
[-9, 2314885530817014877, 3183534901137448992],
[-9, -9, 80]])
I've also thought of using np.nonzero
to get the non-zero indices and then iterate over them and subtract the elements, but my arrays can be quite large and can contain either almost all zeros or almost no zeros, so in the latter case, it could become a expensive operation in terms of time.
Is there a simple way to achieve my desired result?
Upvotes: 2
Views: 4438
Reputation: 19
As you think first, you can performed what you want with a mask:
a[a != 0] = a[a != 0] - b[a != 0]
a
# Output:
array([[-9, -9, -9],
[-9, 0, 0],
[-9, -9, 0]])
Upvotes: 0
Reputation: 1859
Well, I found a trick for this. we can convert all non-zero values of a
to 1 and we will multiply it with b
which will make all values of b to zero at the same index where a
values are
a = np.array([[1, 2, 3], [4, 0, 0], [7, 8, 0]])
b = np.array([[10, 11, 12], [13, 14, 15], [16, 17, 18]])
c = a.copy()
# convert all non-zero values to 1
c[c!=0]=1
# match the 0
d = c*b
# now we will subtract d from a
a-d
output
array([[-9, -9, -9],
[-9, 0, 0],
[-9, -9, 0]])
Hope it helped :)
Upvotes: 0
Reputation: 4510
Try this:
import numpy as np
a = np.array([[1, 2, 3], [4, 0, 0], [7, 8, 0]])
b = np.array([[10, 11, 12], [13, 14, 15], [16, 17, 18]])
sub = np.where(a, a-b, a)
print(sub)
Output:
[[-9 -9 -9]
[-9 0 0]
[-9 -9 0]]
Upvotes: 3