Alina
Alina

Reputation: 2261

Repeat rows of a 2D array

I have a numpy array and I want to repeat it n times while preserving the original order of the rows:

>>>a
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])

Desired ouput (for n =2):

>>>a
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])

I found a np.repeat function, however, it doesnt preserve the original order of the columns. Is there any other in-built function or a trick that will repeat the array while preserving the order?

Upvotes: 3

Views: 1079

Answers (7)

user27397474
user27397474

Reputation: 11

def repeat(arr,n):
    arr2=np.zeros((n,arr.size));
    arr2[:,:]=arr
    return arr2

where n is the number of rows you want and arr is a 1d array that you wnat to repeat

A function like this could also help.

In case you want to test

s1=np.arange(0,4)
s3=repeat(s1,5)
print(s3)

Further if you want to repeat columns

def repeat2(arr,n):
    arr2=np.zeros((arr.size,n));
    arr2[:,:]=arr[:,np.newaxis]
    return arr2

Upvotes: 1

TavoGLC
TavoGLC

Reputation: 919

You can also try

b=np.append(a,a).reshape(np.shape(a)[0]*2,np.shape(a)[1])

Output

array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])

Upvotes: 0

Siddharth Satpathy
Siddharth Satpathy

Reputation: 3043

You can try numpy.tile().

This is how you can use numpy.tile to repeat your array while saving the original order:

import numpy as np

a = np.array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])

n = 5
b = np.tile(a, (n,1))
print b

Output:

[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]
 [ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]
 [ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]
 [ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]
 [ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]] 

Upvotes: 0

hpaulj
hpaulj

Reputation: 231345

This is one case where the fill pattern for np.resize is useful:

In [82]: arr = np.arange(12).reshape(3,4)
In [83]: np.resize(arr,(6,4))
Out[83]: 
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])

(The resize method is different.)

Upvotes: 1

Sheldore
Sheldore

Reputation: 39042

This is another way of doing it. I have also added some time comparison against @coldspeed's solution

n = 2
a_new = np.tile(a.flatten(), n) 
a_new.reshape((n*a.shape[0], a.shape[1]))
# array([[ 0,  1,  2,  3],
#        [ 4,  5,  6,  7],
#        [ 8,  9, 10, 11],
#        [ 0,  1,  2,  3],
#        [ 4,  5,  6,  7],
#        [ 8,  9, 10, 11]])

Performance comparison with coldspeed's solution

My method for n = 10000

a = np.array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
n = 10000

def tile_flatten(a, n):
    a_new = np.tile(a.flatten(), n).reshape((n*a.shape[0], a.shape[1])) 
    return a_new

%timeit tile_flatten(a,n)
# 149 µs ± 20.2 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)   

coldspeed's solution 1 for n = 10000

a = np.array([[ 0,  1,  2,  3],
   [ 4,  5,  6,  7],
   [ 8,  9, 10, 11]])
n = 10000

def concatenate_repeat(a, n):
    a_new =  np.concatenate(np.repeat(a[None, :], n, axis=0), axis=0)
    return a_new

%timeit concatenate_repeat(a,n)
# 7.61 ms ± 1.37 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)

coldspeed's solution 2 for n = 10000

a = np.array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
n = 10000

def broadcast_reshape(a, n):
    a_new =  np.broadcast_to(a, (n, *a.shape)).reshape(-1, a.shape[1])
    return a_new

%timeit broadcast_reshape(a,n)
# 162 µs ± 29.8 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

@user2357112's solution

def tile_only(a, n):
    a_new = np.tile(a, (n, 1))
    return a_new

%timeit tile_only(a,n)
# 142 µs ± 21.8 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

Upvotes: 2

user2357112
user2357112

Reputation: 280251

numpy.repeat is for repetition on an element-wise basis. For repeating the array as a whole, you want numpy.tile.

numpy.tile(a, (2, 1))

The tuple is the number of repetitions in each axis. You want 2 in the first and 1 in the second, so the tuple is (2, 1).

Upvotes: 2

cs95
cs95

Reputation: 402303

Use np.repeat, followed by np.concatenate:

np.concatenate(np.repeat(a[None, :], n, axis=0), axis=0)

array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])

Another option is to use np.broadcast_to:

np.broadcast_to(a, (n, *a.shape)).reshape(-1, a.shape[1])

array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])

Upvotes: 2

Related Questions