简体   繁体   中英

use a vector as an index for another matrix

Assume we have the following matrix:

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

and we have the following vector:

V=[0,3,2]

we want to build the following matrix:

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

Basically, we want to use each element of V as index for M which is M[V[0],0] is 19, M[V[1],1] is 50, and M[V[2],2] is 44. What is the efficient to this using numpy and without for-loop?

I can do it as follow:

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

but is there a better way?

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

M[V,[0,1,2]] produces the 1d array: array([19, 50, 44]) . The rest expands it to 4 rows.

A alternate way to expand it:

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

With tile , each row is a copy of the original row. A different way of 'expanding' the row uses strides:

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

In this case each row shares the same data. For large arrays it saves on space. But if you do M2[1,1]=30 , you will end up changing the whole column. It's a variation on broadcasting: M[V, [0,1,2]][None,:] . It comes down to, 'why do you need 4 identical rows?'.


One more way, taking advantage of how Python 'multiplies' a list:

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

On some quick tests, this is actually the fastest, but I don't know how it scales.

use numpy.diagonal first, then 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]])

or numpy.tile :

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM