I would like to stack N rows of a 3D array one after the other to form a 4D array. I would like to start with the first N rows, i.e. rows = 1, ..., N, and always progress one row, i.e. the next N rows would be rows = 2, ..., N 1. That means the first N rows of the 3D array become the first row of the 4D array. The next N rows of the 3D array become the second row of the 4D array, and so on.
I've already found a way to solve my problem. However, the code is inefficient and it takes forever to compute a large 3D array with many rows. Here is what I did:
import numpy as np
N = 3
X = (np.ones((5,3)).transpose()*np.array([1,2,3,4,5])).transpose()
X = np.dstack((X, 2*X))
Z = np.empty((0, N, X.shape[1], X.shape[2]))
for i in range(N-1, X.shape[0]):
temp1 = X[i-N 1:i 1, :, :]
temp1 = np.expand_dims(temp1, axis=0)
Z = np.append(Z, temp1, axis=0)
I hope the code makes it clear what my goal is.
Thanks in advance for your help.
CodePudding user response:
The part that makes your solutions slow, probably is the np.append operation as internally memory for the array has to be (re-)allocated for each loop iteration. For large arrays this can be quite some overhead. From your code snippet I assume the length of Z
is kown prior to the loop, so this modification could probably speed up your code:
import numpy as np
N = 3
X = (np.ones((5,3)).transpose()*np.array([1,2,3,4,5])).transpose()
X = np.dstack((X, 2*X))
n_z = X.shape[0] - N 1
Z = np.empty((n_z, N, X.shape[1], X.shape[2]))
for idx, i in enumerate(range(N-1, X.shape[0])):
Z[idx] = X[i-N 1:i 1, :, :]