Numpy - 用向量行创建矩阵

ful*_*hex 6 python numpy python-2.7 numpy-broadcasting

我有一个矢量[x,y,z,q],我想创建一个矩阵:

[[x,y,z,q],
 [x,y,z,q],
 [x,y,z,q],
...
 [x,y,z,q]]
Run Code Online (Sandbox Code Playgroud)

有m行.我认为这可以通过一些聪明的方式,使用广播来完成,但我只能想到用for循环来做.

Div*_*kar 11

当然可以在列上broadcasting添加m零之后,就像这样 -

np.zeros((m,1),dtype=vector.dtype) + vector
Run Code Online (Sandbox Code Playgroud)

现在,NumPy已经拥有了np.tile完全相同任务的内置功能-

np.tile(vector,(m,1))
Run Code Online (Sandbox Code Playgroud)

样品运行 -

In [496]: vector
Out[496]: array([4, 5, 8, 2])

In [497]: m = 5

In [498]: np.zeros((m,1),dtype=vector.dtype) + vector
Out[498]: 
array([[4, 5, 8, 2],
       [4, 5, 8, 2],
       [4, 5, 8, 2],
       [4, 5, 8, 2],
       [4, 5, 8, 2]])

In [499]: np.tile(vector,(m,1))
Out[499]: 
array([[4, 5, 8, 2],
       [4, 5, 8, 2],
       [4, 5, 8, 2],
       [4, 5, 8, 2],
       [4, 5, 8, 2]])
Run Code Online (Sandbox Code Playgroud)

您也可以np.repeat在扩展其尺寸后使用np.newaxis/None相同的效果,如下所示 -

In [510]: np.repeat(vector[None],m,axis=0)
Out[510]: 
array([[4, 5, 8, 2],
       [4, 5, 8, 2],
       [4, 5, 8, 2],
       [4, 5, 8, 2],
       [4, 5, 8, 2]])
Run Code Online (Sandbox Code Playgroud)

您也可以使用它integer array indexing来获取复制,如下所示 -

In [525]: vector[None][np.zeros(m,dtype=int)]
Out[525]: 
array([[4, 5, 8, 2],
       [4, 5, 8, 2],
       [4, 5, 8, 2],
       [4, 5, 8, 2],
       [4, 5, 8, 2]])
Run Code Online (Sandbox Code Playgroud)

最后np.broadcast_to,你可以简单地创建一个2D输入视图vector,因此这几乎是免费的,没有额外的内存需求.所以,我们只是做 -

In [22]: np.broadcast_to(vector,(m,len(vector)))
Out[22]: 
array([[4, 5, 8, 2],
       [4, 5, 8, 2],
       [4, 5, 8, 2],
       [4, 5, 8, 2],
       [4, 5, 8, 2]])
Run Code Online (Sandbox Code Playgroud)

运行时测试 -

这是一个比较各种方法的快速运行时测试 -

In [12]: vector = np.random.rand(10000)

In [13]: m = 10000

In [14]: %timeit np.broadcast_to(vector,(m,len(vector)))
100000 loops, best of 3: 3.4 µs per loop # virtually free!

In [15]: %timeit np.zeros((m,1),dtype=vector.dtype) + vector
10 loops, best of 3: 95.1 ms per loop

In [16]: %timeit np.tile(vector,(m,1))
10 loops, best of 3: 89.7 ms per loop

In [17]: %timeit np.repeat(vector[None],m,axis=0)
10 loops, best of 3: 86.2 ms per loop

In [18]: %timeit vector[None][np.zeros(m,dtype=int)]
10 loops, best of 3: 89.8 ms per loop
Run Code Online (Sandbox Code Playgroud)