Reputation: 2261
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
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
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
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
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
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
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
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