John Kealy
John Kealy

Reputation: 1883

Trouble with dimensional order when cloning a 1-dimensional numpy array to 3 dimensions

I'm having trouble finding a way to clone a 1-D numpy array to create a 3-D array. Say for example, I have

z = np.array([0, 2, 3, 5, 7, 9, 10])

This represents a vertical column in 3-D space (let's say it's in meters, for example). I want to create a horizontal dimension (x, y), so that the final array has dimensions (len(z), len(x), len(y)) , where each column at each x,y point is the same. I'm doing this so that I can match the spatial dimensions to other 3-D data that I have.

So with the array z as input, and given horizontal dimensions of, say, ndimx=3, ndimy=2, I want to find a function that outputs the array

np.array([ [[0, 0], [0, 0], [0, 0]],  
           [[2, 2], [2, 2], [2, 2]],       
           [[3, 3], [3, 3], [3, 3]],       
           [[5, 5], [5, 5], [5, 5]],       
           [[7, 7], [7, 7], [7, 7]],       
           [[9, 9], [9, 9], [9, 9]],       
           [[10, 10], [10, 10], [10, 10]] ])

which has a shape of (7, 3, 2). This seemed trivial to me at first, but after ages of experimenting with np.dstack(), np.astype(), np.repeat(), and transposes with ().T, I can't get the dimensional order right.

That's the critical thing here, that the vertical column is the first dimension. I'm willing to bet the answer is indeed trivial, I just can't find the magic numpy function that will do it.

Any suggestions?

Upvotes: 1

Views: 39

Answers (2)

hpaulj
hpaulj

Reputation: 231385

In [360]: z = np.array([0, 2, 3, 5, 7, 9, 10])
In [361]: z1 = np.stack([z,z], axis=1)
In [362]: z2 = np.stack([z1,z1,z1],axis=1)
In [363]: z2
Out[363]: 
array([[[ 0,  0],
        [ 0,  0],
        [ 0,  0]],

       [[ 2,  2],
        [ 2,  2],
        [ 2,  2]],

       [[ 3,  3],
        [ 3,  3],
        [ 3,  3]],

      ... 
       [[10, 10],
        [10, 10],
        [10, 10]]])

Upvotes: 0

Divakar
Divakar

Reputation: 221574

We can simply get a view into input z with np.broadcast_to with no additional memory overhead and as such virtually free on performance -

np.broadcast_to(z[:,None,None],(len(z),ndimx,ndimy))

Sample run -

In [23]: z
Out[23]: array([ 0,  2,  3,  5,  7,  9, 10])

In [24]: ndimx=3; ndimy=2

In [25]: np.broadcast_to(z[:,None,None],(len(z),ndimx,ndimy))
Out[25]: 
array([[[ 0,  0],
        [ 0,  0],
        [ 0,  0]],

       [[ 2,  2],
        [ 2,  2],
        [ 2,  2]],

       [[ 3,  3],
        [ 3,  3],
        [ 3,  3]],

       [[ 5,  5],
        [ 5,  5],
        [ 5,  5]],

       [[ 7,  7],
        [ 7,  7],
        [ 7,  7]],

       [[ 9,  9],
        [ 9,  9],
        [ 9,  9]],

       [[10, 10],
        [10, 10],
        [10, 10]]])

Upvotes: 1

Related Questions