Numpy tile for complex transformation

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]]])

Leave a Reply