2016-06-03 11 views
1

Ich suche nach einem effizienten Weg, elementweise Gleichheit in einem 3D- oder N-D-Array zu finden, zum Beispiel gleichen Wert auf RGB-Pixel eines Bildes. Einige Testdaten:Elementweise Gleichheit in 3-D-Array mit beliebig großen Achsen

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]) 

Ich kann mich drei Möglichkeiten, von denen die ersten nicht gut auf mehr Dimensionen nicht verallgemeinern:

equal_mask = (d[0] == d[1]) & (d[0] == d[2]) 

oder

equal_mask = d.min(axis=0) == d.max(axis=0) 

oder, vielleicht besser:

equal_mask = numpy.logical_and.reduce(d == d[0]) 

Gibt es einen effi Lösung

EDIT: Ich sollte klarstellen, dass ich nicht n-D, 3-D mit unterschiedlicher Länge auf der ersten Achse gemeint, zum Beispiel d = numpy.array([a,b,c,a,b,c]).

Antwort

1

Divakar und Colonel Beauvel Lösungen sowohl andeuten, dass ich meine Lösung d[0] == d[0] etwas schneller durch Überspringen der Überprüfung vornehmen:

numpy.logical_and.reduce(d[1:] == d[0]) 

In Bezug auf die Effizienz und die Fähigkeit, beliebig Größe Achsen zu arbeiten, scheint dies noch die beste Lösung zu sein, so weit ...

+0

'd [1:,:]' könnte als 'd [1:]' verkürzt werden. – Divakar

+0

Danke für die Vorschläge. Ich werde meine aktuelle Antwort als akzeptiert markieren, es sei denn, es kommt etwas Besseres. – Benjamin

+0

Das klingt fair für mich! – Divakar

1

Vielleicht dieses:

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

Was ist hier los? Die Tupel-/Stern-Syntax ist neu für mich; Mir ist nicht klar, wie dies einer Reduktion entspricht. – Benjamin

+0

Es ist der Splat-Operator und es wird zum Auspacken verwendet. Das heißt, Sie nehmen alle Elemente einer Liste und übergeben diese an eine Funktion. In diesem Beispiel ist die Funktion 'np.logical_and' und wir übergeben die Elemente' a' und 'b' aus der Liste' [a, b] ' –

+0

Danke, das habe ich angenommen. Daher funktioniert es nur für den 3-D-Fall, aber nicht für den n-D-Fall. – Benjamin

1

Hier ist ein Ansatz für nD Array Fälle, die für alle 0' s diferentiations entlang der ersten Achse sieht -

(np.diff(d,axis=0)==0).all(0) 

Probenlauf Ergebnisse zu verifizieren -

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 

Wie sich herausstellt, scheint diese Methode langsam zu sein er als numpy.logical_and.reduce basierte Methode wie in der Frage aufgeführt. Also, an diesem Punkt sieht es so aus, als würde man dabei bleiben.

+0

@Benjamin Ah ja, das ist noch schlauer! Toller Job :) – Divakar