I have two arrays, one of shape (4, 6, 1). I want to append the 2 values stored in another array of shape (2,) to the third dimension so that I end up with a resulting array of shape (4, 6, 3).
How do I go about this?
As an example we have:
arr1 = np.repeat(np.array([[[1], [1], [1], [1], [1], [1]]]), 4, axis=0)
arr2 = np.array([2, 3])
So we have arr1 =
arr1 = [[[1]
[1]
[1]
[1]
[1]
[1]]
[[1]
[1]
[1]
[1]
[1]
[1]]
[[1]
[1]
[1]
[1]
[1]
[1]]
[[1]
[1]
[1]
[1]
[1]
[1]]]
And we want to end up with:
[[[1 2 3]
[1 2 3]
[1 2 3]
[1 2 3]
[1 2 3]
[1 2 3]]
[[1 2 3]
[1 2 3]
[1 2 3]
[1 2 3]
[1 2 3]
[1 2 3]]
[[1 2 3]
[1 2 3]
[1 2 3]
[1 2 3]
[1 2 3]
[1 2 3]]
[[1 2 3]
[1 2 3]
[1 2 3]
[1 2 3]
[1 2 3]
[1 2 3]]]
Keep in mind I am generating the arrays here like this so we have an example to work off.
I have found a very convoluted way of doing it, but it feels there must be some numpy wizardry or functionality that should work.
This is what I found:
arr1 = np.repeat(np.array([[[1], [1], [1], [1], [1], [1]]]), 4, axis=0)
arr2 = np.array([2, 3])
arr2 = np.repeat(arr2, 6, axis=0)
arr2 = arr2.reshape(2, 6).T
arr2 = arr2.reshape(1, self.lag, -1)
arr2 = np.repeat(arr2, 4, axis=0)
print(arr1.shape)
print(arr2.shape)
arr3 = np.append(arr1, arr2, axis=2)
print(arr3)
We get the result we want then, but is there a better way?
CodePudding user response:
IIUC, you can broadcast the first 2 dimensions of arr2
with numpy.broadcast_to
, then dstack
:
np.dstack([arr1, np.broadcast_to(arr2, arr1.shape[:2] arr2.shape)])
output:
array([[[1, 2, 3],
[1, 2, 3],
[1, 2, 3],
[1, 2, 3],
[1, 2, 3],
[1, 2, 3]],
[[1, 2, 3],
[1, 2, 3],
[1, 2, 3],
[1, 2, 3],
[1, 2, 3],
[1, 2, 3]],
[[1, 2, 3],
[1, 2, 3],
[1, 2, 3],
[1, 2, 3],
[1, 2, 3],
[1, 2, 3]],
[[1, 2, 3],
[1, 2, 3],
[1, 2, 3],
[1, 2, 3],
[1, 2, 3],
[1, 2, 3]]])
CodePudding user response:
np.tile
can do the two repeats
for you:
arr1 = np.repeat(np.array([[[1], [1], [1], [1], [1], [1]]]), 4, axis=0)
arr2 = np.array([2, 3])
arr2 = np.repeat(arr2, 6, axis=0)
arr2 = arr2.reshape(2, 6).T
arr2 = arr2.reshape(1, 6, -1)
arr2 = np.repeat(arr2, 4, axis=0)
arr2.shape
Out[129]: (4, 6, 2)
np.tile(np.array((2,3))[None,None,:], (4,6,1)).shape
Out[130]: (4, 6, 2)
np.concatenate((arr1,np.tile(np.array((2,3))[None,None,:], (4,6,1))), axis=2).shape
Out[132]: (4, 6, 3)
Another idea is to create the target array first, and fill it. The (2,) arr2
fills the (4,6,2) space by broadcasting
(as though it were (1,1,2) shape).
res = np.zeros((4,6,3),int)
res[:,:,[0]] = arr1
res[:,:,1:] = np.array((2,3))