Suppose there’s an array
arr = np.array([[1,2,3], [4,5,6]])
My goal is to repeat N = 2
times the elements that are on axis = 0
, so the desired output is
array([[[1., 4.],
[1., 4.]],
[[2., 5.],
[2., 5.]],
[[3., 6.],
[3., 6.]]])
I’ve tried np.ones((2,2))*arr.T[:,:,None]
, but the output differs
array([[[1., 1.],
[4., 4.]],
[[2., 2.],
[5., 5.]],
[[3., 3.],
[6., 6.]]])
Is there an easy way to fix that? In guess it’s the matter of transposition, but I’m not sure how to achieve that.
EDIT: I’ve found the answer. It is:
np.transpose(np.ones((2,2))*arr.T[:,:,None], axes = tuple([0, 2, 1]))
>Solution :
One method
(s0,s1)=arr.strides
np.lib.stride_tricks.as_strided(arr, shape=(3, 2, 2), strides=(s1,0,s0))
Note that it is basically free: it does nothing, and return the same arr
. Just, a change of strides make iterations goes along arr
axis 1 for the new array axis 0; just repeat for axis 1; and along arr
axis 0 for the new array axis 2.
A generalization to all sizes of 2D arr
, and all repetitions
def myrepeat(arr, n):
(sh0,sh1)=arr.shape
(st0,st1)=arr.strides
return np.lib.stride_tricks.as_strided(arr, shape=(sh1,n,sh0), strides=(st1,0,st0))
# Example
arr=np.arange(20).reshape(4,5)
myrepeat(arr,3)
Returns
array([[[ 0, 5, 10, 15],
[ 0, 5, 10, 15],
[ 0, 5, 10, 15]],
[[ 1, 6, 11, 16],
[ 1, 6, 11, 16],
[ 1, 6, 11, 16]],
[[ 2, 7, 12, 17],
[ 2, 7, 12, 17],
[ 2, 7, 12, 17]],
[[ 3, 8, 13, 18],
[ 3, 8, 13, 18],
[ 3, 8, 13, 18]],
[[ 4, 9, 14, 19],
[ 4, 9, 14, 19],
[ 4, 9, 14, 19]]])