使用向量作为另一个矩阵的索引

时间:2015-01-27 08:02:50

标签: python numpy matrix scipy vectorization

假设我们有以下矩阵:

M=[[ 19.  1.  8.]
 [ 3.  6.  900.]
 [ 4.  11.  44.]
 [ 2.  50.  12.]]

我们有以下向量:

V=[0,3,2]

我们想要构建以下矩阵:

P=[[ 19.  50.  44.]
 [ 19.  50.  44.]
 [ 19.  50.  44.]
 [ 19.  50.  44.]]

基本上,我们想要使用V的每个元素作为M的索引,其中M [V [0],0]是19,M [V [1],1]是50,并且M [V [2] ,2]是44.使用numpy和没有for循环的效率是多少?

我可以这样做:

temp=M[V[np.arange(v.shape[0])],np.arange(v.shape[0])]
P=np.tile(temp,(M.shape[0],1))

但有更好的方法吗?

2 个答案:

答案 0 :(得分:3)

M[V,[0,1,2]][None,:].repeat(4,0)

M[V,[0,1,2]]生成1d数组:array([19, 50, 44])。其余的将它扩展为4行。

扩展它的另一种方法:

np.tile(M[V,[0,1,2]],[4,1])

使用tile,每行都是原始行的副本。一种不同的方式来扩大'该行使用步幅:

M2=np.broadcast_arrays(M[V,[0,1,2]],np.zeros((4,1)))[0]

在这种情况下,每一行共享相同的数据。对于大型阵列,它节省了空间。但如果你M2[1,1]=30,你最终会改变整个专栏。它是广播的变体:M[V, [0,1,2]][None,:]。它归结为,“为什么你需要4个相同的行?'。


还有一种方法,就是利用Python'倍增'清单:

M[np.array(V*4).reshape(4,-1), [0,1,2]]

在一些快速测试中,这实际上是最快的,但我不知道它是如何扩展的。

答案 1 :(得分:1)

首先使用numpy.diagonal,然后使用numpy.repeat

In [168]: dia = tg[v].diagonal()[None,:]

In [169]: dia.repeat(4, axis=0)
Out[169]: 
array([[19, 50, 44],
       [19, 50, 44],
       [19, 50, 44],
       [19, 50, 44]])

numpy.tile

In [172]: np.tile(dia, (4, 1))
Out[172]: 
array([[19, 50, 44],
       [19, 50, 44],
       [19, 50, 44],
       [19, 50, 44]])