“克隆”行或列向量

有时将行或列向量“克隆”到matrix是有用的。 通过克隆我的意思是转换行向量如

[1,2,3] 

成matrix

 [[1,2,3] [1,2,3] [1,2,3] ] 

或列向量如

 [1 2 3 ] 

 [[1,1,1] [2,2,2] [3,3,3] ] 

在matlab或八度,这是很容易做到的:

  x = [1,2,3] a = ones(3,1) * x a = 1 2 3 1 2 3 1 2 3 b = (x') * ones(1,3) b = 1 1 1 2 2 2 3 3 3 

我想用numpy重复这个,但是不成功

 In [14]: x = array([1,2,3]) In [14]: ones((3,1)) * x Out[14]: array([[ 1., 2., 3.], [ 1., 2., 3.], [ 1., 2., 3.]]) # so far so good In [16]: x.transpose() * ones((1,3)) Out[16]: array([[ 1., 2., 3.]]) # DAMN # I end up with In [17]: (ones((3,1)) * x).transpose() Out[17]: array([[ 1., 1., 1.], [ 2., 2., 2.], [ 3., 3., 3.]]) 

为什么不是第一种方法(在[16]中)工作? 有没有办法以更优雅的方式在Python中实现这个任务?

这是一个优雅的,Pythonic的方式来做到这一点:

 >>> array([[1,2,3],]*3) array([[1, 2, 3], [1, 2, 3], [1, 2, 3]]) >>> array([[1,2,3],]*3).transpose() array([[1, 1, 1], [2, 2, 2], [3, 3, 3]]) 

[16]的问题似乎是转置对数组没有影响。 你可能想要一个matrix,而不是:

 >>> x = array([1,2,3]) >>> x array([1, 2, 3]) >>> x.transpose() array([1, 2, 3]) >>> matrix([1,2,3]) matrix([[1, 2, 3]]) >>> matrix([1,2,3]).transpose() matrix([[1], [2], [3]]) 

使用numpy.tile

 >>> tile(array([1,2,3]), (3, 1)) array([[1, 2, 3], [1, 2, 3], [1, 2, 3]]) 

或重复列:

 >>> tile(array([[1,2,3]]).transpose(), (1, 3)) array([[1, 1, 1], [2, 2, 2], [3, 3, 3]]) 

首先请注意,在numpy的广播操作中,通常不需要复制行和列。 看到这个和这个说明。

但要做到这一点, 重复和新的可能是最好的方法

 In [12]: x = array([1,2,3]) In [13]: repeat(x[:,newaxis], 3, 1) Out[13]: array([[1, 1, 1], [2, 2, 2], [3, 3, 3]]) In [14]: repeat(x[newaxis,:], 3, 0) Out[14]: array([[1, 2, 3], [1, 2, 3], [1, 2, 3]]) 

这个例子是针对一个行向量的,但是将其应用于一个列向量是有希望的。 重复似乎拼写得很好,但你也可以通过在你的例子乘法

 In [15]: x = array([[1, 2, 3]]) # note the double brackets In [16]: (ones((3,1))*x).transpose() Out[16]: array([[ 1., 1., 1.], [ 2., 2., 2.], [ 3., 3., 3.]]) 

我觉得在numpy中使用广播是最好的,而且速度更快

我做了如下比较

 import numpy as np b = np.random.randn(1000) In [105]: %timeit c = np.tile(b[:, newaxis], (1,100)) 1000 loops, best of 3: 354 µs per loop In [106]: %timeit c = np.repeat(b[:, newaxis], 100, axis=1) 1000 loops, best of 3: 347 µs per loop In [107]: %timeit c = np.array([b,]*100).transpose() 100 loops, best of 3: 5.56 ms per loop 

使用广播速度约快15倍

np.broadcast_to甚至比np.tile更快:

 x = np.arange(9) %timeit np.broadcast_to(x, (6,9)) 100000 loops, best of 3: 3.6 µs per loop %timeit np.tile(x, (6,1)) 100000 loops, best of 3: 8.4 µs per loop 

但最快的是@ tom10的方法:

 %timeit np.repeat(x[np.newaxis, :], 6, axis=0) 100000 loops, best of 3: 3.15 µs per loop 

您可以使用

 np.tile(x,3).reshape((4,3)) 

平铺将生成向量的代表

并重塑将赋予它你想要的形状