2017-06-01 3 views
2

Ich versuche, die Funktion as_strided von numpy.lib.stride_tricks zu verwenden, um Sub-Serie aus einem größeren 2D-Array zu extrahieren, aber ich hatte Mühe, das richtige zu schreiben für das strides Argument.Schiebe Fenster entlang der letzten Achse eines 2D-Arrays zu einem 3D-Array mit NumPy Schritten

Nehmen wir an, ich habe eine Matrix m, die 5 1D Array der Länge enthält (a=) 10. Ich möchte Sub-1D-Arrays der Länge (b=) 4 für jedes 1D-Array in m extrahieren.

import numpy 
from numpy.lib.stride_tricks import as_strided 

a, b = 10, 4 
m = numpy.array([range(i,i+a) for i in range(5)]) 

# first try 
sub_m = as_strided(m, shape=(m.shape[0], m.shape[1]-b+1, b)) 
print sub_m.shape # (5,7,4) which is what i expected 
print sub_m[-1,-1,-1] # Some unexpected strange number: 8227625857902995061 

# second try with strides argument 
sub_m = as_strided(m, shape=(m.shape[0], m.shape[1]-b+1, b), strides=(m.itemize,m.itemize,m.itemize)) 
# gives error, see below 

AttributeError: 'numpy.ndarray' object has no attribute 'itemize'

Wie Sie es mir gelingt, bekommen die richtige Form für sub_m in meinem ersten Versuch zu sehen. Allerdings kann ich nicht finden, was in Informationen strides=()

schreiben:

m = [[ 0 1 2 3 4 5 6 7 8 9] 
[ 1 2 3 4 5 6 7 8 9 10] 
[ 2 3 4 5 6 7 8 9 10 11] 
[ 3 4 5 6 7 8 9 10 11 12] 
[ 4 5 6 7 8 9 10 11 12 13]] 

Erwartete Ausgabe:

sub_n = [ 
     [[0 1 2 3] [1 2 3 4] ... [5 6 7 8] [6 7 8 9]] 
     [[1 2 3 4] [2 3 4 5] ... [6 7 8 9] [7 8 9 10]] 
     [[2 3 4 5] [3 4 5 6] ... [7 8 9 10] [8 9 10 11]] 
     [[3 4 5 6] [4 5 6 7] ... [8 9 10 11] [9 10 11 12]] 
     [[4 5 6 7] [5 6 7 8] ... [9 10 11 12] [10 11 12 13]] 
     ] 

bearbeiten: Ich habe viel mehr Daten, das ist der Grund, warum ich möchte verwenden as_strided (Effizienz)

+0

Was ist die Form der erwarteten Ausgabe? Stellen Sie sich vor, die Eingabe hat die Form (m, n) und Sie haben eine Schrittlänge von sagen wir "L". – Divakar

+0

Erwartete Ausgangsform: (5,7,4) (m, n, L), mit L = m-4 + 1 – Nuageux

+0

Vielleicht meinen Sie (m, n-L + 1, L)? – Divakar

Antwort

1

Hier ist ein Ansatz mit np.lib.stride_tricks.as_strided -

def strided_lastaxis(a, L): 
    s0,s1 = a.strides 
    m,n = a.shape 
    return np.lib.stride_tricks.as_strided(a, shape=(m,n-L+1,L), strides=(s0,s1,s1)) 

Bit Erklärung auf Fortschritte für as_strided:

Wir haben 3D-Schritte, dass Schritte um ein Element entlang der letzten/dritten Achse, so s1 es für die letzte Achse schreitend. Die zweite Achse schreitet um das gleiche Element "Abstand" voran, also auch dafür s1. Für die erste Achse ist das Schreiten die gleiche wie die Schrittlänge der ersten Achse des Arrays, da wir uns in der nächsten Reihe bewegen, also dort s0.

Probelauf -

In [46]: a 
Out[46]: 
array([[0, 5, 6, 2, 3, 6, 7, 1, 4, 8], 
     [2, 1, 3, 7, 0, 3, 5, 4, 0, 1]]) 

In [47]: strided_lastaxis(a, L=4) 
Out[47]: 
array([[[0, 5, 6, 2], 
     [5, 6, 2, 3], 
     [6, 2, 3, 6], 
     [2, 3, 6, 7], 
     [3, 6, 7, 1], 
     [6, 7, 1, 4], 
     [7, 1, 4, 8]], 

     [[2, 1, 3, 7], 
     [1, 3, 7, 0], 
     [3, 7, 0, 3], 
     [7, 0, 3, 5], 
     [0, 3, 5, 4], 
     [3, 5, 4, 0], 
     [5, 4, 0, 1]]]) 
+0

Danke! Es klappt. Allerdings verstehe ich immer noch nicht, was ich in das letzte Argument bringen soll. Woher kommt '(s0, s1, s1)'? Ich würde wirklich schätzen, wenn Sie weitere Details hinzufügen können, so nächstes Mal muss ich nicht fragen :) – Nuageux

+0

@Nuageux Heartfelt Entschuldigung Sir! Kommentare hinzugefügt. – Divakar

+0

Vielen Dank für Ihre Erklärung, es ist nicht das erste Mal, dass ich mit dieser Funktion kämpfe, nächstes Mal denke ich, dass ich nicht werde! (PS: Warum der Herr?) – Nuageux

Verwandte Themen