Benjamin
Benjamin

Reputation: 11860

Element-wise equality in 3-D array with arbitrarily sized axes

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

Answers (3)

Benjamin
Benjamin

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

Divakar
Divakar

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

Colonel Beauvel
Colonel Beauvel

Reputation: 31181

Maybe this one:

np.logical_and(*(d[0,:]==d[1:,:]))

Upvotes: 0

Related Questions