假设我们有以下矩阵:
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))
但有更好的方法吗?
答案 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]])