【问题标题】:How to assign elements into the diagonal of a 3d matrix efficiently?如何有效地将元素分配到 3d 矩阵的对角线上?
【发布时间】:2018-07-15 22:36:17
【问题描述】:
a=np.zeros((3,3,3))
b=np.arange(3)
c=np.arange(9).reshape(3,3)

我想将数组bc 的元素沿3d 矩阵(张量)a 相对于特定轴的对角线(或对角线上方/下方)放置。

我厌倦了numpy.diagflat,但它只适用于二维矩阵。

例如,如何制作下面的矩阵?

array([[[ 0.,  0.,  0.],
        [ 0.,  1.,  0.],
        [ 0.,  0.,  2.]],

       [[ 0.,  0.,  0.],
        [ 0.,  1.,  0.],
        [ 0.,  0.,  2.]],

       [[ 0.,  0.,  0.],
        [ 0.,  1.,  0.],
        [ 0.,  0.,  2.]]])

【问题讨论】:

    标签: python numpy matrix scipy diagonal


    【解决方案1】:

    如果稀疏矩阵可以满足您的需求,这里有一些资源:

    http://www.janeriksolem.net/sparray-sparse-n-dimensional-arrays-in.html

    sparse 3d matrix/array in Python?

    【讨论】:

      【解决方案2】:

      对于主对角线,您可以使用np.einsum。例如:

      >> np.einsum('iii->i', a)[...] = b
      >>> a
      array([[[ 0.,  0.,  0.],
              [ 0.,  0.,  0.],
              [ 0.,  0.,  0.]],
      
             [[ 0.,  0.,  0.],
              [ 0.,  1.,  0.],
              [ 0.,  0.,  0.]],
      
             [[ 0.,  0.,  0.],
              [ 0.,  0.,  0.],
              [ 0.,  0.,  2.]]])
      

      或者:

      >>> np.einsum('iji->ji', a)[...] = c
      >>> a
      array([[[ 0.,  0.,  0.],
              [ 3.,  0.,  0.],
              [ 6.,  0.,  0.]],
      
             [[ 0.,  1.,  0.],
              [ 0.,  4.,  0.],
              [ 0.,  7.,  0.]],
      
             [[ 0.,  0.,  2.],
              [ 0.,  0.,  5.],
              [ 0.,  0.,  8.]]])
      

      编辑:广播正常:

      >>> np.einsum('ijj->ij', a)[...] = b
      >>> a
      array([[[ 0.,  0.,  0.],
              [ 0.,  1.,  0.],
              [ 0.,  0.,  2.]],
      
             [[ 0.,  0.,  0.],
              [ 0.,  1.,  0.],
              [ 0.,  0.,  2.]],
      
             [[ 0.,  0.,  0.],
              [ 0.,  1.,  0.],
              [ 0.,  0.,  2.]]])
      

      下对角线也可以使用,但比较棘手,因为需要进行一些手动切片。例如:

      >>> a=np.zeros((3,3,3))
      >>> np.einsum('iij->ij', a[:2,1:])[...] = c[1:]
      >>> a
      array([[[ 0.,  0.,  0.],
              [ 3.,  4.,  5.],
              [ 0.,  0.,  0.]],
      
             [[ 0.,  0.,  0.],
              [ 0.,  0.,  0.],
              [ 6.,  7.,  8.]],
      
             [[ 0.,  0.,  0.],
              [ 0.,  0.,  0.],
              [ 0.,  0.,  0.]]])
      

      【讨论】:

      • numpy 标签中的后起之秀!
      • 你今天的心情似乎很好。或者你说的是einsum
      • Thx,np.einsum 是一个一个分配元素还是同时分配所有元素?
      • 不,这只是一种恭维。也许如果我最终阅读了一些关于 einsum 的教程,我将能够在 numpy 标签中获得一些代表;)
      • 两者都没有。它的作用是在原始数组中创建一个可写视图。然后我们使用这个视图来手动分配。我的直觉是,至少对于大型数组来说,这应该是相当快的。
      猜你喜欢
      • 2016-06-02
      • 1970-01-01
      • 2012-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-18
      • 1970-01-01
      相关资源
      最近更新 更多