großes Problem für array-slicing
in mehrdimensionale Tensoren/Arrays zu üben!
Wir werden das Ausgangs-Array als mehrdimensionale 6D
-Array initialisieren und es einfach in Scheiben schneiden und die vier Arrays, die als 4D
-Arrays umgeformt werden, zuweisen. Die Absicht ist, jegliches Stapeln/Verketten zu vermeiden, da dies speziell beim Arbeiten mit großen Arrays teuer wäre, indem stattdessen mit der Neugestaltung von Eingabe-Arrays gearbeitet wird, die lediglich Ansichten sind.
Hier ist die Umsetzung -
out = np.zeros((N,2,3,N,2,3),dtype=A.dtype)
out[:,0,:,:,0,:] = A.reshape(N,3,N,3)
out[:,0,:,:,1,:] = D.reshape(N,3,N,3)
out[:,1,:,:,0,:] = C.reshape(N,3,N,3)
out[:,1,:,:,1,:] = B.reshape(N,3,N,3)
out.shape = (6*N,6*N)
Nur ein bisschen mehr zu erklären, wir hatten:
|------------------------ Axes for selecting A, B, C, D
np.zeros((N,2,3,N,2,3),dtype=A.dtype)
|------------------------- Axes for selecting A, B, C, D
So zwischen auszuwählen diese beiden Achsen (zweite und fünfte) von Längen (2x2) = 4
verwendet wurden die vier Eingänge.
Runtime Test
Approaches -
def original_app(A, B, C, D):
final = np.zeros((6*N,6*N),dtype=A.dtype)
for i in range(N):
for j in range(N):
for k in range(3):
for l in range(3):
final[6*i + k][6*j + l] = A[3*i+k][3*j+l]
final[6*i + k + 3][6*j + l + 3] = B[3*i+k][3*j+l]
final[6*i + k + 3][6*j + l] = C[3*i+k][3*j+l]
final[6*i + k][6*j + l + 3] = D[3*i+k][3*j+l]
return final
def slicing_app(A, B, C, D):
out = np.zeros((N,2,3,N,2,3),dtype=A.dtype)
out[:,0,:,:,0,:] = A.reshape(N,3,N,3)
out[:,0,:,:,1,:] = D.reshape(N,3,N,3)
out[:,1,:,:,0,:] = C.reshape(N,3,N,3)
out[:,1,:,:,1,:] = B.reshape(N,3,N,3)
return out.reshape(6*N,6*N)
Timings und Verifizierung -
In [147]: # Setup input arrays
...: N = 200
...: A = np.random.randint(11,99,(3*N,3*N))
...: B = np.random.randint(11,99,(3*N,3*N))
...: C = np.random.randint(11,99,(3*N,3*N))
...: D = np.random.randint(11,99,(3*N,3*N))
...:
In [148]: np.allclose(slicing_app(A, B, C, D), original_app(A, B, C, D))
Out[148]: True
In [149]: %timeit original_app(A, B, C, D)
1 loops, best of 3: 1.63 s per loop
In [150]: %timeit slicing_app(A, B, C, D)
100 loops, best of 3: 9.26 ms per loop
(nicht zum Thema) | Ich dachte mir, das einzige Mal, dass ich jemanden "numpythonisch" sagen hörte, war eine andere Person in SO. Aber dann habe ich überprüft und das warst du auch :) – miradulo
@Mitch Fast ein * Tonic *. – Divakar
Ja, ich kämpfe mit verschiedenen Möglichkeiten, Schleifen auf numpythonische Weise zu machen. Das Auge ist ein Fehler, es sollte Null sein. – NunodeSousa