2012-06-12 3 views
11

Der einfachste Weg, meine Frage zu erklären, mit einem Beispiel sein kann, so lassen Sie mich einige Felder definieren:Wie sauber Index numpy Arrays mit Arrays (oder irgendetwas anderes, das zusätzlich unterstützt, so dass es ausgeglichen werden kann)

>>> test = arange(25).reshape((5,5)) 
>>> test 
array([[ 0, 1, 2, 3, 4], 
     [ 5, 6, 7, 8, 9], 
     [10, 11, 12, 13, 14], 
     [15, 16, 17, 18, 19], 
     [20, 21, 22, 23, 24]]) 
>>> Xinds = array([1,2,3]) 
>>> Yinds = array([1,2,3]) 

Nun gehe ich könnte, wenn ich die Elemente in den Zeilen 1, 2 und 3 und in Spalte 0 wollte:

>>> test[Yinds,0] 
array([ 5, 10, 15]) 

wenn ich die Elemente in den Zeilen 1, 2 und 3 und alle Spalten wollte, Ich könnte gehen:

>>> test[Yinds, :] 
array([[ 5, 6, 7, 8, 9], 
     [10, 11, 12, 13, 14], 
     [15, 16, 17, 18, 19]]) 

Allerdings, wenn ich versuche, dies zu erweitern, um die Elemente in den Zeilen 1, 2 und 3 und Spalten 1, 2 und 3 zu erhalten, - Überraschung! - Ich bekomme stattdessen die Elemente in (1,1), (2,2) und (3,3)

>>> test[Yinds, Xinds] 
array([ 6, 12, 18]) 

Statt dessen, was ich will:

>>> test[Yinds, :][:, Xinds] 
array([[ 6, 7, 8], 
     [11, 12, 13], 
     [16, 17, 18]]) 
>>> test[1:4,1:4] 
array([[ 6, 7, 8], 
     [11, 12, 13], 
     [16, 17, 18]]) 

Ich weiß, ich könnte Definiere ein Slice, aber ich möchte den Indizes einen Offset hinzufügen können (zB Yinds + Offset), und das kann nicht mit Slices gemacht werden.

Ich könnte so etwas wie

>>> xStart = 1 
>>> xEnd = 4 
>>> yStart = 1 
>>> yEnd = 4 

>>> offset = 1 
>>> test[yStart+offset:yEnd+offset, xStart+offset:xEnd+offset] 
... 

oder

>>> Xinds = array([1,4]) 
>>> Yinds = array([1,4]) 

>>> offset = 1 
>>> test[slice(*(Yinds+offset)), slice(*(Xinds+offset))] 
... 

tun Aber weder ist besonders sauber.

Affe patchen den Additions-Operator in Slice scheint keine Option zu sein, und erben von Slice, um den Operator hinzuzufügen, scheint nicht zu arbeiten; Ich bekomme den Fehler, "Typ 'Slice' ist kein akzeptabler Basistyp". (* Grummel * Das wäre kein Problem in Ruby * Grumble *)

Also, meine Frage ist, was ist der sauberste Weg auf ein (mehr als 1 dimensionales) Sub-Array mit etwas, das gespeichert werden kann und Offset?

Optionen so weit:

  • Test [Yinds + Offset:] [:, Xinds + Offset]
  • Test [YStart + Offset: yEnd + Offset, xStart Offset +: xEnd + Offset]
  • Test [Scheibe (* (Yinds + Offset)), Scheibe (* (Xinds + Offset))]

Antwort

12

ich bin nicht ganz sicher, was Sie wollen, aber ix_ würde vielleicht helfen? Ich denke, ich habe Leute gesehen, die mehr über Numpy wissen, als ich es in ähnlichen Kontexten verwende.

>>> from numpy import array, arange, ix_ 
>>> a = arange(25).reshape(5,5) 
>>> Xinds = array([1,2,3]) 
>>> Yinds = array([1,2,3]) 
>>> a 
array([[ 0, 1, 2, 3, 4], 
     [ 5, 6, 7, 8, 9], 
     [10, 11, 12, 13, 14], 
     [15, 16, 17, 18, 19], 
     [20, 21, 22, 23, 24]]) 
>>> a[ix_(Xinds, Yinds)] 
array([[ 6, 7, 8], 
     [11, 12, 13], 
     [16, 17, 18]]) 
>>> a[ix_(Xinds+1, Yinds)] 
array([[11, 12, 13], 
     [16, 17, 18], 
     [21, 22, 23]]) 
>>> Y2inds = array([1,3,4]) 
>>> a[ix_(Xinds, Y2inds)] 
array([[ 6, 8, 9], 
     [11, 13, 14], 
     [16, 18, 19]]) 
>>> a[ix_(Xinds, Y2inds-1)] 
array([[ 5, 7, 8], 
     [10, 12, 13], 
     [15, 17, 18]]) 
+0

Das scheint zu sein, was ich suche. Vielen Dank. – lnmaurer