【问题标题】:use a vector as an index for another matrix使用向量作为另一个矩阵的索引
【发布时间】:2015-03-25 18:53:30
【问题描述】:

假设我们有以下矩阵:

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))

但是有更好的方法吗?

【问题讨论】:

    标签: python numpy matrix scipy vectorization


    【解决方案1】:
    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]]
    

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        猜你喜欢
        • 2011-08-19
        • 1970-01-01
        • 1970-01-01
        • 2022-11-02
        • 2016-06-22
        • 2020-07-08
        • 2015-06-16
        • 2012-09-01
        相关资源
        最近更新 更多