Python: Concatenate (or clone) a numpy array N times
Question:
I want to create an MxN numpy array by cloning a Mx1 ndarray N times. Is there an efficient pythonic way to do that instead of looping?
Btw the following way doesn’t work for me (X is my Mx1 array) :
numpy.concatenate((X, numpy.tile(X,N)))
since it created a [M*N,1] array instead of [M,N]
Answers:
Have you tried this:
n = 5
X = numpy.array([1,2,3,4])
Y = numpy.array([X for _ in xrange(n)])
print Y
Y[0][1] = 10
print Y
prints:
[[1 2 3 4]
[1 2 3 4]
[1 2 3 4]
[1 2 3 4]
[1 2 3 4]]
[[ 1 10 3 4]
[ 1 2 3 4]
[ 1 2 3 4]
[ 1 2 3 4]
[ 1 2 3 4]]
You are close, you want to use np.tile
, but like this:
a = np.array([0,1,2])
np.tile(a,(3,1))
Result:
array([[0, 1, 2],
[0, 1, 2],
[0, 1, 2]])
If you call np.tile(a,3)
you will get concatenate
behavior like you were seeing
array([0, 1, 2, 0, 1, 2, 0, 1, 2])
http://docs.scipy.org/doc/numpy/reference/generated/numpy.tile.html
You could use vstack:
numpy.vstack([X]*N)
e.g.
>>> import numpy as np
>>> X = np.array([1,2,3,4])
>>> N = 7
>>> np.vstack([X]*N)
array([[1, 2, 3, 4],
[1, 2, 3, 4],
[1, 2, 3, 4],
[1, 2, 3, 4],
[1, 2, 3, 4],
[1, 2, 3, 4],
[1, 2, 3, 4],
[1, 2, 3, 4],
[1, 2, 3, 4]])
An alternative to np.vstack
is np.array
used this way (also mentioned by @bluenote10 in a comment):
x = np.arange([-3,4]) # array([-3, -2, -1, 0, 1, 2, 3])
N = 3 # number of time you want the array repeated
X0 = np.array([x] * N)
gives:
array([[-3, -2, -1, 0, 1, 2, 3],
[-3, -2, -1, 0, 1, 2, 3],
[-3, -2, -1, 0, 1, 2, 3]])
You can also use meshgrid
this way (granted it’s longer to write, and kind of pulling hairs but you get yet another possibility and you may learn something new along the way):
X1,_ = np.meshgrid(a,np.empty([N]))
>>> X1
shows:
array([[-3, -2, -1, 0, 1, 2, 3],
[-3, -2, -1, 0, 1, 2, 3],
[-3, -2, -1, 0, 1, 2, 3]])
Checking that all these are equivalent:
-
meshgrid and np.array approach
X0 == X1
result:
array([[ True, True, True, True, True, True, True],
[ True, True, True, True, True, True, True],
[ True, True, True, True, True, True, True]])
-
np.array and np.vstack approach
X0 == np.vstack([x] * 3)
result:
array([[ True, True, True, True, True, True, True],
[ True, True, True, True, True, True, True],
[ True, True, True, True, True, True, True]])
-
np.array and np.tile approach
X0 == np.tile(x,(N,1))
result:
array([[ True, True, True, True, True, True, True],
[ True, True, True, True, True, True, True],
[ True, True, True, True, True, True, True]])
I want to create an MxN numpy array by cloning a Mx1 ndarray N times. Is there an efficient pythonic way to do that instead of looping?
Btw the following way doesn’t work for me (X is my Mx1 array) :
numpy.concatenate((X, numpy.tile(X,N)))
since it created a [M*N,1] array instead of [M,N]
Have you tried this:
n = 5
X = numpy.array([1,2,3,4])
Y = numpy.array([X for _ in xrange(n)])
print Y
Y[0][1] = 10
print Y
prints:
[[1 2 3 4]
[1 2 3 4]
[1 2 3 4]
[1 2 3 4]
[1 2 3 4]]
[[ 1 10 3 4]
[ 1 2 3 4]
[ 1 2 3 4]
[ 1 2 3 4]
[ 1 2 3 4]]
You are close, you want to use np.tile
, but like this:
a = np.array([0,1,2])
np.tile(a,(3,1))
Result:
array([[0, 1, 2],
[0, 1, 2],
[0, 1, 2]])
If you call np.tile(a,3)
you will get concatenate
behavior like you were seeing
array([0, 1, 2, 0, 1, 2, 0, 1, 2])
http://docs.scipy.org/doc/numpy/reference/generated/numpy.tile.html
You could use vstack:
numpy.vstack([X]*N)
e.g.
>>> import numpy as np
>>> X = np.array([1,2,3,4])
>>> N = 7
>>> np.vstack([X]*N)
array([[1, 2, 3, 4],
[1, 2, 3, 4],
[1, 2, 3, 4],
[1, 2, 3, 4],
[1, 2, 3, 4],
[1, 2, 3, 4],
[1, 2, 3, 4],
[1, 2, 3, 4],
[1, 2, 3, 4]])
An alternative to np.vstack
is np.array
used this way (also mentioned by @bluenote10 in a comment):
x = np.arange([-3,4]) # array([-3, -2, -1, 0, 1, 2, 3])
N = 3 # number of time you want the array repeated
X0 = np.array([x] * N)
gives:
array([[-3, -2, -1, 0, 1, 2, 3],
[-3, -2, -1, 0, 1, 2, 3],
[-3, -2, -1, 0, 1, 2, 3]])
You can also use meshgrid
this way (granted it’s longer to write, and kind of pulling hairs but you get yet another possibility and you may learn something new along the way):
X1,_ = np.meshgrid(a,np.empty([N]))
>>> X1
shows:
array([[-3, -2, -1, 0, 1, 2, 3],
[-3, -2, -1, 0, 1, 2, 3],
[-3, -2, -1, 0, 1, 2, 3]])
Checking that all these are equivalent:
-
meshgrid and np.array approach
X0 == X1
result:
array([[ True, True, True, True, True, True, True],
[ True, True, True, True, True, True, True],
[ True, True, True, True, True, True, True]])
-
np.array and np.vstack approach
X0 == np.vstack([x] * 3)
result:
array([[ True, True, True, True, True, True, True],
[ True, True, True, True, True, True, True],
[ True, True, True, True, True, True, True]])
-
np.array and np.tile approach
X0 == np.tile(x,(N,1))
result:
array([[ True, True, True, True, True, True, True],
[ True, True, True, True, True, True, True],
[ True, True, True, True, True, True, True]])