2016-09-30 2 views
1

ich überprüfen möchten, ob ein beliebiges Objekt mit einem bestimmten Attribut in meinem numpy Array ist:Python: Überprüfen Sie, ob ein numpy Array ein Objekt mit bestimmten Attribut enthält

class Test: 
def __init__(self, name): 
    self.name = name 

l = numpy.empty((2,2), dtype=object) 
l[0][0] = Test("A") 
l[0][1] = Test("B") 
l[1][0] = Test("C") 
l[1][1] = Test("D") 

Ich weiß, dass für folgende Codezeile arbeiten eine Liste, aber was ist der alternative Prozess für ein numpy Array?

print numpy.any(l[:,0].name == "A") 
+0

möglich dupliziert. Siehe diesen Beitrag http://stackoverflow.com/questions/7088625/what-is-the-most-efficient-way-to-check-if-a-value-exists-in-a-umpy-array –

+0

Ich glaube das ist eine andere Situation, da ich eine Reihe von Objekten habe. [Der andere Beitrag] (http://stackoverflow.com/questions/7088625/what-ist-most-efficient-way-to-check-if-a-value-exis-in-a-numpy-array) fragen, wie man über die Existenz eines Wertes in einem Array herausfinden kann. –

+0

Objekt-Arrays sind wenig mehr als verherrlichte Listen. Sie können eine 2D-Form haben, aber sie haben nicht die mathematischen Fähigkeiten eines regulären Arrays. Warum benutzt du sie? – hpaulj

Antwort

1

Eine einfache Möglichkeit wäre die Erstellung Ihres Array-Objekts durch Erben von Numpys ndarray-Objekt. Dann verwenden Sie eine benutzerdefinierte Funktion zur Überprüfung der Existenz des Objekts basierend auf dem Attribut name:

In [71]: class Myarray(np.ndarray): 
    ....:   def __new__(cls, inputarr): 
    ....:     obj = np.asarray(inputarr).view(cls) 
    ....:     return obj 
    ....:   def custom_contain(self, name): 
    ....:     return any(obj.name == name for obj in self.flat) 

Demo:

In [4]: A = np.empty((2,2),dtype=object)  
In [8]: A.flat[:] = [Test("A"), Test("B"), Test("C"), Test("D")] 

In [9]: A 
Out[9]: 
array([[<__main__.Test instance at 0x7fae0a14ddd0>, 
     <__main__.Test instance at 0x7fae0a14de18>], 
     [<__main__.Test instance at 0x7fae0a14de60>, 
     <__main__.Test instance at 0x7fae0a14dea8>]], dtype=object) 

In [11]: A = Myarray(A) 

In [12]: A.custom_contain('C') 
Out[12]: True 

In [13]: A.custom_contain('K') 
Out[13]: False 
+0

Vielen Dank für Ihren informativen Kommentar, aber Sie haben immer noch eine Liste als Ihr Array, das vollständig mit jedem() funktioniert. –

+0

Wie wäre es, den Code zu diesem changeing: l = np.empty ((2,2), dtype = Objekt) l = myarray (l) Druck l l [0] [0] = Test (“ A ") l [0] [1] = Test (" B ") l [1] [0] = Test (" C ") l [1] [1] = Test (" D ") print l.custom_contain ('C') –

+1

Die Antwort wiederholt sich über das Array, als wäre es eine Liste. Das sind typische Objektarray-Operationen – hpaulj

0

Ich bin eindeutig nicht beherrschen numpy konnte aber nicht einfach etwas tun wie:

numpy.any([ x.name=='A' for x in l[:,0] ]) 

edit: (Google sagt mir, dass) es möglich ist, Arrays iterieren mit nditer; ist das was du willst?

numpy.any([ x.name=='A' for x in numpy.nditer(l) ]) 
+0

Sie haben Recht, aber das ist nur Suche Spalte 0 –

+0

Ich habe meine Antwort bearbeitet; Ich bin mir immer noch nicht sicher, was Sie tun wollen. –

1

Es gibt eine Reihe SO Fragen über das Objekt dtype Arrays, und sogar einige über das Erhalten oder die Prüfung der Eigenschaften der Elemente eines solchen Arrays. Der allgemeine Punkt ist, dass ein solches Array sich ähnlich wie eine Liste verhält. Zum größten Teil müssen Sie über das Array iterieren, als wäre es eine Liste. Die meisten coolen Dinge, die Sie mit numerischen Arrays wie add, multiply usw. tun können, gelten nicht. Oder Ihre Objekte müssen bestimmte Methoden implementieren, damit die Aktionen an die Objekte weitergegeben werden.

In [15]: class Test: 
    ...:  def __init__(self,name): 
    ...:   self.name=name 
    ...:  def __repr__(self): # added for nice display 
    ...:   return 'Test:%s'%self.name 
    ...:  
In [16]: A = np.empty((2,2),dtype=object) 

ich auf einmal alle Werte zuweisen können flat[:] und Liste:

In [17]: A.flat[:]=[Test('A'),Test('B'),Test('C'),Test('D')] 

In [18]: A  # try this display without the `repr` 
Out[18]: 
array([[Test:A, Test:B], 
     [Test:C, Test:D]], dtype=object) 

diese gibt False zurück, weil ich nicht ein cmp für die Klasse definiert haben; das ist Test('A')==Test('A') ist auch falsch.

In [19]: Test('A') in A 
Out[19]: False 


In [20]: A[0,1].name 
Out[20]: 'B' 

Dies ist wahr, weil es sich um eine Identitätsprüfung

In [21]: A[0,1] in A 
Out[21]: True 

Da A ist 2d ist eine einfache Liste Verständnis auf es nicht funktioniert, zumindest nicht für die Prüfung Attribute. a in diesem Fall ist eine Reihe von A, ein Objektarray 1d:

In [23]: [a.name for a in A] 
... 
AttributeError: 'numpy.ndarray' object has no attribute 'name' 

Um die Namen zu bekommen I auf A.flat iteriert haben; Ich kann den in Test auf die resultierende Liste anwenden:

In [24]: [a.name for a in A.flat] 
Out[24]: ['A', 'B', 'C', 'D'] 
In [25]: 'B' in [a.name for a in A.flat] 
Out[25]: True 

np.vectorize ist eine Art und Weise des Schreibens Funktionen, die auf Arrays von verschiedenen Formen arbeiten. Es verwendet np.frompyfunc, was in diesem Fall genauso gut funktioniert, wenn nicht besser.

In [27]: foo = np.frompyfunc(lambda a: a.name, 1,1) 
In [28]: foo(A) 
Out[28]: 
array([['A', 'B'], 
     ['C', 'D']], dtype=object) 
In [29]: 'C' in foo(A) 
Out[29]: True 

Oder ich könnte eine Version festlegen, funktioniert die name Gleichheitstest. Beachten Sie dies dauert 2 Eingänge

In [30]: bar = np.frompyfunc(lambda a,b: b == a.name, 2, 1) 

In [32]: bar(A,'C') 
Out[32]: 
array([[False, False], 
     [True, False]], dtype=object) 

Ich kann sogar Test 2 Arrays gegeneinander mit Rundfunk:

In [37]: bar(A,np.array(['A','D'])[:,None,None]) 
Out[37]: 
array([[[True, False], 
     [False, False]], 

     [[False, False], 
     [False, True]]], dtype=object) 

frompyfunc Iterierten als [a for a in A.flat] tut, aber ist etwas schneller, und wirft die ganze Kraft von numpy Sendung an der Aufgabe.

Verwandte Themen