【问题标题】:Numpy modify ndarray diagonalNumpy修改ndarray对角线
【发布时间】:2011-09-12 22:27:34
【问题描述】:

在 numpy 中有什么方法可以获取对数组对角线的引用吗? 我希望我的数组对角线除以某个因子 谢谢

【问题讨论】:

    标签: python numpy


    【解决方案1】:

    如果X 是您的数组并且c 是因素,

    X[np.diag_indices_from(X)] /= c
    

    请参阅 Numpy 手册中的 diag_indices_from

    【讨论】:

      【解决方案2】:

      使用arr.flat[::n+1] 可以快速访问正方形(n,n) numpy 数组的对角线:

      n = 1000
      c = 20
      a = np.random.rand(n,n)
      
      a[np.diag_indices_from(a)] /= c # 119 microseconds
      a.flat[::n+1] /= c # 25.3 microseconds
      

      【讨论】:

        【解决方案3】:

        np.fill_diagonal 函数相当快:

        np.fill_diagonal(a, a.diagonal() / c)
        

        a 是您的数组,c 是您的因素。在我的机器上,这种方法与@kwgoodman 的a.flat[::n+1] /= c 方法一样快,而且在我看来更清晰一些(但没有那么流畅)。

        【讨论】:

          【解决方案4】:

          以上3种方法比较:

          import numpy as np
          import timeit
          
          n = 1000
          c = 20
          a = np.random.rand(n,n)
          a1 = a.copy()
          a2 = a.copy()
          a3 = a.copy()
          
          t1 = np.zeros(1000)
          t2 = np.zeros(1000)
          t3 = np.zeros(1000)
          
          for i in range(1000):
              start = timeit.default_timer()
              a1[np.diag_indices_from(a1)] /= c 
              stop = timeit.default_timer()
              t1[i] = start-stop
          
              start = timeit.default_timer()
              a2.flat[::n+1] /= c
              stop = timeit.default_timer()
              t2[i] = start-stop
          
              start = timeit.default_timer()
              np.fill_diagonal(a3,a3.diagonal() / c)
              stop = timeit.default_timer()
              t3[i] = start-stop
          
          print([t1.mean(), t1.std()])
          print([t2.mean(), t2.std()])
          print([t3.mean(), t3.std()])
          
          [-4.5693619907979154e-05, 9.3142851395411316e-06]
          [-2.338075107036275e-05, 6.7119609571872443e-06]
          [-2.3731951987429056e-05, 8.0455946813059586e-06]
          

          所以你可以看到np.flat 方法是最快的,但也很勉强。当我再运行几次时,有时fill_diagonal 方法会稍微快一些。但就可读性而言,它可能值得使用 fill_diagonal 方法。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2015-09-25
            • 2018-10-10
            • 1970-01-01
            • 1970-01-01
            • 2012-04-15
            • 2021-05-11
            • 1970-01-01
            • 2015-05-08
            相关资源
            最近更新 更多