2016-08-29 4 views
2

Wenn np.lib.stride_tricks.as_strided verwenden, wie kann ich verwalten 2D ein Array mit dem verschachtelten Arrays als Datenwert? Gibt es einen bevorzugten effizienten Ansatz?Numpy Rollfenster über 2D-Array, als 1D-Array mit verschachtelten Array als Datenwert

Insbesondere, wenn ich ein 2D np.array suchen wie folgt, wobei jedes Datenelement in einem 1D-Array ist ein Array mit einer Länge von 2:

[[1., 2.],[3., 4.],[5.,6.],[7.,8.],[9.,10.]...] 

ich für überrollen neu zu gestalten wollen wie folgt:

[[[1., 2.],[3., 4.],[5.,6.]], 
[[3., 4.],[5.,6.],[7.,8.]], 
[[5.,6.],[7.,8.],[9.,10.]], 
    ... 
] 

Ich habe mir ähnliche Antworten angesehen (zB this rolling window function), allerdings kann ich das interne Array/Tupel nicht verändern.

Zum Beispiel mit einer Fensterlänge von 3: Ich habe ein shape von (len(seq)+3-1, 3, 2) versucht und ein stride von (2 * 8, 2 * 8, 8), aber kein Glück. Vielleicht fehlt mir etwas Offensichtliches?

Prost.


EDIT: Es ist einfach, eine funktionsgleiche Lösung mit Python eingebaute Funktionen zu erzeugen, aber (die beispielsweise np.arange ähnlich wie Divakar-Lösung unter Verwendung optimiert werden kann), was etwa as_strided mit? Aus meiner Sicht könnte dies für eine hocheffiziente Lösung verwendet werden?

Antwort

2

Was mit Ihrem as_strided Studie falsch war? Für mich geht das.

In [28]: x=np.arange(1,11.).reshape(5,2) 
In [29]: x.shape 
Out[29]: (5, 2) 
In [30]: x.strides 
Out[30]: (16, 8) 
In [31]: np.lib.stride_tricks.as_strided(x,shape=(3,3,2),strides=(16,16,8)) 
Out[31]: 
array([[[ 1., 2.], 
     [ 3., 4.], 
     [ 5., 6.]], 

     [[ 3., 4.], 
     [ 5., 6.], 
     [ 7., 8.]], 

     [[ 5., 6.], 
     [ 7., 8.], 
     [ 9., 10.]]]) 

Bei meinem ersten bearbeiten benutzte ich einen int Array, musste so (8,8,4) für die Schritte verwenden.

Ihre Form könnte falsch sein. Wenn es zu groß ist, beginnt es Werte am Ende des Datenpuffers zu sehen.

[[ 7.00000000e+000, 8.00000000e+000], 
    [ 9.00000000e+000, 1.00000000e+001], 
    [ 8.19968827e-257, 5.30498948e-313]]]) 

Hier ändert nur die Anzeigemethode, die 7, 8, 9, 10 sind immer noch da. Solche Slots zu schreiben könnte gefährlich sein und andere Teile deines Codes durcheinander bringen. as_strided ist am besten, wenn es für schreibgeschützte Zwecke verwendet wird. Schreibt/Sätze sind kniffliger.

+0

Hm, vielleicht habe ich etwas sehr offensichtliches verpasst ... Danke fürs Herumspielen, ich werde es so schnell wie möglich verifizieren! Leider war ich zu beschäftigt, um mich am letzten Tag mit dem dazugehörigen Projekt zu setzen. – Kappers

+0

Danke, ich beantwortete tatsächlich meine eigene Frage und war zu dumm um es zu realisieren - seufz. Am Ende brachte dies keine Leistung auf den Tisch - ich muss noch einmal nachsehen, wenn ich eine komplexere/höhere Dimension Datenstruktur oder vielleicht nur größere Datenmengen verwende. – Kappers

3

IIUC könnte man so etwas tun -

def rolling_window2D(a,n): 
    # a: 2D Input array 
    # n: Group/sliding window length 
    return a[np.arange(a.shape[0]-n+1)[:,None] + np.arange(n)] 

Probelauf -

In [110]: a 
Out[110]: 
array([[ 1, 2], 
     [ 3, 4], 
     [ 5, 6], 
     [ 7, 8], 
     [ 9, 10]]) 

In [111]: rolling_window2D(a,3) 
Out[111]: 
array([[[ 1, 2], 
     [ 3, 4], 
     [ 5, 6]], 

     [[ 3, 4], 
     [ 5, 6], 
     [ 7, 8]], 

     [[ 5, 6], 
     [ 7, 8], 
     [ 9, 10]]]) 
+0

Danke, das ist funktional korrekt! Leistungsmäßig ist dies jedoch einer 'as_strided' Lösung, die ich zu erreichen versuchte, nicht unterlegen? Natürlich sollte dies schneller als jede eingebaute 'Bereichs'-Lösung sein. – Kappers

+0

@Kappers Nun, ich habe nicht wirklich herumgespielt mit 'strides' viel, so kann ich auf die Leistung Aspekt nicht kommentieren. Also, zumindest als eine Alternative zu den Schritten, falls die "Fortschritt" -Methode für Sie nicht funktioniert, das habe ich aus der Frage gezogen. – Divakar

0

Sie Aufgabe ist ähnlich this one. Also habe ich es leicht verändert.

# Rolling window for 2D arrays in NumPy 
import numpy as np 

def rolling_window(a, shape): # rolling window for 2D array 
    s = (a.shape[0] - shape[0] + 1,) + (a.shape[1] - shape[1] + 1,) + shape 
    strides = a.strides + a.strides 
    return np.lib.stride_tricks.as_strided(a, shape=s, strides=strides) 

x = np.array([[1,2],[3,4],[5,6],[7,8],[9,10],[3,4],[5,6],[7,8],[11,12]]) 
y = np.array([[3,4],[5,6],[7,8]]) 
found = np.all(np.all(rolling_window(x, y.shape) == y, axis=2), axis=2) 
print(found.nonzero()[0]) 
Verwandte Themen