Für eine massive Leistung könnten wir strides
hier integrieren. Der Trick besteht darin, das ursprüngliche Array mit dem geschnittenen Array zu verknüpfen, das am vorletzten Element endet, und dann Schiebefenster mit Längen aufzunehmen, die gleich der Länge des ursprünglichen Arrays sind.
Daher wäre die Implementierung sein -
def strided_method(ar):
a = np.concatenate((ar, ar[:-1]))
L = len(ar)
n = a.strides[0]
return np.lib.stride_tricks.as_strided(a, (L,L), (n,n), writeable=False)
Der Ausgang schreibgeschützt und eine Ansicht der verketteten Anordnung werden würde, und als solches würde fast unabhängig von der Feldgröße eine konstante Zeit. Dies bedeutet eine äußerst effiziente Lösung. Wenn Sie eine beschreibbare Ausgabe mit eigenem Speicherplatz benötigen, erstellen Sie dort eine Kopie, wie später gezeigt.
Probelauf -
In [51]: foo = np.array([1,2,3,4])
In [52]: strided_method(foo)
Out[52]:
array([[1, 2, 3, 4],
[2, 3, 4, 1],
[3, 4, 1, 2],
[4, 1, 2, 3]])
Runtime Test -
In [53]: foo = np.random.randint(0,9,(1000))
# @cᴏʟᴅsᴘᴇᴇᴅ's loopy soln
In [54]: %timeit np.array([np.roll(foo, -x) for x in np.arange(foo.shape[0])])
100 loops, best of 3: 12.7 ms per loop
In [55]: %timeit strided_method(foo)
100000 loops, best of 3: 7.46 µs per loop
In [56]: %timeit strided_method(foo).copy()
1000 loops, best of 3: 454 µs per loop
Hat eine der veröffentlichten Lösungen für Sie funktioniert? – Divakar