93

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]

stelios
  • 2,679
  • 5
  • 31
  • 41
  • 3
    `tile(X,N)` will do it. – gg349 Mar 25 '14 at 12:26
  • 1
    The (num)Pythonic way is not to do this but to use [broadcasting](http://scipy-lectures.github.io/intro/numpy/numpy.html#broadcasting) instead of `tile` and `repmat` and the like. – YXD Mar 25 '14 at 14:44
  • 2
    You might not need to expand it. If, for example, it is added or multiplied with a [M,N] or [1,N] matrix, the result will be [M,N]. `numpy` broadcasts it for you. In fact you could use that to expand the array: `X + np.zeros(N)`. – hpaulj Mar 25 '14 at 19:17

4 Answers4

156

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

Cory Kramer
  • 114,268
  • 16
  • 167
  • 218
32

You could use vstack:

numpy.vstack([X]*N)

or array (credit to bluenote10 below):

numpy.array([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]])
Lee
  • 29,398
  • 28
  • 117
  • 170
  • 1
    vstack works when we need a multidimensional array to get repeated, for example: a=[[1,2,3,4][5,6,7,8]] becomes [[1,2,3,4][5,6,7,8][1,2,3,4][5,6,7,8]] with np.vstack([a]*2). The other approaches get you [[1,2,3,4][1,2,3,4][5,6,7,8][5,6,7,8]] – Sidharth N. Kashyap Jul 01 '20 at 04:37
  • 2
    Is `vstack` even needed? Why not just `np.array([X] * N)`? – bluenote10 Apr 20 '21 at 16:29
  • 1
    This doesn't work for N=1. You should just use `np.array` instead of `np.vstack` – Evidlo May 14 '23 at 18:56
4

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]]
Samy Arous
  • 6,794
  • 13
  • 20
3

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]])
calocedrus
  • 2,430
  • 20
  • 25