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

3
假设我们有以下矩阵:
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个回答

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

M[V,[0,1,2]]会生成一个一维数组: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

先使用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]])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接