“克隆”行或列向量
有时将行或列向量“克隆”到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))
平铺将生成向量的代表
并重塑将赋予它你想要的形状