连接(或克隆)一个数字数组 N 次

我想通过克隆一个 Mx1 ndarray N 次来创建一个 MxN numpy 数组。有没有一种有效的 Python 方式来代替循环?

顺便说一下,下面的方法对我不起作用(X 是我的 Mx1数组) :

   numpy.concatenate((X, numpy.tile(X,N)))

因为它创建了一个[ M * N,1]数组而不是[ M,N ]

85544 次浏览

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]])