PabloRdrRbl
PabloRdrRbl

Reputation: 247

Create 3D array from a 2D array by replicating/repeating along the first axis

Suppose I have a n × m array, i.e.:

array([[ 1.,  2.,  3.],
       [ 4.,  5.,  6.],
       [ 7.,  8.,  9.]])

And I what to generate a 3D array k × n × m, where all the arrays in the new axis are equal, i.e.: the same array but now 3 × 3 × 3.

array([[ 1.,  2.,  3.],
       [ 4.,  5.,  6.],
       [ 7.,  8.,  9.]],

      [[ 1.,  2.,  3.],
       [ 4.,  5.,  6.],
       [ 7.,  8.,  9.]],

      [[ 1.,  2.,  3.],
       [ 4.,  5.,  6.],
       [ 7.,  8.,  9.]]])

How can I get it?

Upvotes: 9

Views: 4910

Answers (4)

Divakar
Divakar

Reputation: 221524

Introduce a new axis at the start with None/np.newaxis and replicate along it with np.repeat. This should work for extending any n dim array to n+1 dim array. The implementation would be -

np.repeat(arr[None,...],k,axis=0)

Sample run -

In [143]: arr
Out[143]: 
array([[ 1.,  2.,  3.],
       [ 4.,  5.,  6.],
       [ 7.,  8.,  9.]])

In [144]: np.repeat(arr[None,...],3,axis=0)
Out[144]: 
array([[[ 1.,  2.,  3.],
        [ 4.,  5.,  6.],
        [ 7.,  8.,  9.]],

       [[ 1.,  2.,  3.],
        [ 4.,  5.,  6.],
        [ 7.,  8.,  9.]],

       [[ 1.,  2.,  3.],
        [ 4.,  5.,  6.],
        [ 7.,  8.,  9.]]])

View-output for memory-efficiency

We can also generate a 3D view and achieve virtually free runtime with np.broadcast_to. More info - here. Hence, simply do -

np.broadcast_to(arr,(3,)+arr.shape) # repeat 3 times

Upvotes: 13

aderchox
aderchox

Reputation: 4074

I think this answer is exactly the answer of Divakar, but the syntax might be a bit easier to understand for a beginner(at least in my case, it is):

a = np.array([[1,2,3],[4,5,6]])
a[np.newaxis,:,:].repeat(3,axis=0)

results in:

array([[[1, 2, 3],
        [4, 5, 6]],

       [[1, 2, 3],
        [4, 5, 6]],

       [[1, 2, 3],
        [4, 5, 6]]])

I learned about np.newaxis here: What is numpy.newaxis and when to use it.

And about numpy.repeat here: numpy.repeat


Here's an example usage I needed this for:

k = np.array([[[111,121,131,141,151],[211,221,231,241,251]],\
              [[112,122,132,142,152],[212,222,232,242,252]],\
              [[113,123,133,143,153],[213,223,233,243,253]]])

filter = np.array([[True,True,True,True,False], 
                   [True,False,False,True,False]])
k[filter[None,...].repeat(3,axis=0)] = 0
print(k)

results in:

[[[  0   0   0   0 151]
  [  0 221 231   0 251]]

 [[  0   0   0   0 152]
  [  0 222 232   0 252]]

 [[  0   0   0   0 153]
  [  0 223 233   0 253]]]

Upvotes: 0

MSeifert
MSeifert

Reputation: 152597

One possibility would be to use default broadcasting to replicate your array:

a = np.arange(1, 10).reshape(3,3)
n = 3
b = np.ones((n, 3, 3)) * a

Which results in the array you wanted:

array([[[ 1.,  2.,  3.],
        [ 4.,  5.,  6.],
        [ 7.,  8.,  9.]],

       [[ 1.,  2.,  3.],
        [ 4.,  5.,  6.],
        [ 7.,  8.,  9.]],

       [[ 1.,  2.,  3.],
        [ 4.,  5.,  6.],
        [ 7.,  8.,  9.]]])

This won't work by default if you want to replicate it along another axis. In that case you would need to be explicit with the dimensions to ensure correct broadcasting.

Upvotes: 0

Yotam Salmon
Yotam Salmon

Reputation: 2411

if you have:

a = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

You can use a list comprehension to generate the duplicate array:

b = [a for x in range(3)]

Then (for numpy):

c = array(b)

Upvotes: 0

Related Questions