Reputation: 5294
I have two 3D boolean arrays of the same shape (let's say (512,512,512)
).
I'd like to check if the True
region of one array is completely included in the second.
Right now the best I've come up with is:
np.all((A * B) == A)
Is there a faster way to do this? Unfortunately this goes inside an inner loop I'm not able to optimize further, so the more I shave from this the better.
Upvotes: 2
Views: 209
Reputation: 221514
Approach #1 : If they are boolean arrays, AND-ing
might be better than multiplication -
((A & B) == A).all()
Approach #2 : Another with counting of True values -
np.count_nonzero(A & B) == np.count_nonzero(A)
Runtime test -
In [225]: A = np.random.rand(512,512,512)>0.5
...: B = np.random.rand(512,512,512)>0.5
In [226]: %timeit np.all((A * B) == A)
...: %timeit ((A & B) == A).all()
...: %timeit np.count_nonzero(A & B) == np.count_nonzero(A)
10 loops, best of 3: 170 ms per loop
10 loops, best of 3: 169 ms per loop
10 loops, best of 3: 57.7 ms per loop
Approach #3 : Short-circuiting at numba level basically looking for if there's any A
True, for which the corresponding B
isn't -
from numba import njit
@njit
def numba_app(a, b):
l = len(a)
out = True
for i in range(l):
if a[i] & ~b[i]:
out = False
break
return out
out = numba_app(A.ravel(), B.ravel())
The timings with this Short-circuiting
method would depend on the data.
Upvotes: 2