Reputation: 11860
I am looking for an efficient way to find element-wise equality in a 3D or N-D array, for example, equal value on RGB pixels of an image. Some test data:
a = numpy.arange(100).reshape((10,10))
b = a.copy()
c = a.copy()
b[5,5] = 1
c[6,6] = 100
d = numpy.array([a,b,c])
I can think of three options, the first of which does not generalize well to more dimensions:
equal_mask = (d[0] == d[1]) & (d[0] == d[2])
or
equal_mask = d.min(axis=0) == d.max(axis=0)
or, maybe better:
equal_mask = numpy.logical_and.reduce(d == d[0])
Is there a more efficient solution?
EDIT: I should clarify that I didn't mean n-D, 3-D with different length on the first axis, for example d = numpy.array([a,b,c,a,b,c])
.
Upvotes: 1
Views: 76
Reputation: 11860
Divakar and Colonel Beauvel's solutions both hint that I can make my solution a bit faster by skipping the check d[0] == d[0]
:
numpy.logical_and.reduce(d[1:] == d[0])
In terms of efficiency and ability to to work on arbitrarily size axes, this still appears to be the best solution, so far...
Upvotes: 1
Reputation: 221754
Here's an approach for nD
array cases that looks for all 0'
s diferentiations along the first axis -
(np.diff(d,axis=0)==0).all(0)
Sample run to verify results -
In [46]: d = np.random.randint(0,9,(3,3,5,2,3,4,2))
In [47]: out = (np.diff(d,axis=0)==0).all(0)
In [48]: np.allclose(out,(d[0] == d[1]) & (d[0] == d[2]))
Out[48]: True
As it turns out, this method seems to be slower than numpy.logical_and.reduce
based method as listed in the question. So, at this point looks like sticking with it might be the way to go.
Upvotes: 0