2017-10-21 4 views
3
foo = np.array([1,2,3,4]) 

Ich habe eine numpy Array foo, Ich mag würde in eine ndarry oder einer Matrix, die ähnlich wie diese zu transformieren:Permutationen einer numpy Array in eine ndarray oder Matrix

Irgendwelche Vorschläge
bar = np.array([[1,2,3,4],[2,3,4,1],[3,4,1,2],[4,1,2,3]]) 

wie um dies effizient zu tun, da mein Quell-Array foo in der Größe variieren wird, und ich diese Transformation millionenfach machen muss.

+0

Hat eine der veröffentlichten Lösungen für Sie funktioniert? – Divakar

Antwort

3

Sie könnten np.roll in einer Schleife verwenden.

x = np.array([np.roll(foo, -x) for x in np.arange(foo.shape[0])]) 

print(x) 
array([[1, 2, 3, 4], 
     [2, 3, 4, 1], 
     [3, 4, 1, 2], 
     [4, 1, 2, 3]]) 
3

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 
+1

Wartet auf Sie zu posten! –

2

Diese Matrizen werden Hankel Matrizen genannt. Die meisten Plattformen bieten bereits eine spezifische Routine für ihre Erstellung. Sie können sich auch selbst implementieren, indem Sie die unnötigen Teile entfernen, um die Geschwindigkeit zu erhöhen. Es ist a pretty concise code

from scipy.linalg import hankel 

A = hankel([1,2,3,4], [4,1,2,3]) 
A 
array([[1, 2, 3, 4], 
     [2, 3, 4, 1], 
     [3, 4, 1, 2], 
     [4, 1, 2, 3]]) 

Es scheint, dass es nur ~ 2x langsamer als Divakar-Lösung, die überraschend schnell.