【问题标题】:Re-calculate elements of symmetric matrix using a "i not equal to j" loop in Python在 Python 中使用“i 不等于 j”循环重新计算对称矩阵的元素
【发布时间】:2020-12-11 04:34:35
【问题描述】:

相关矩阵是一个对称矩阵,这意味着它的上对角元素和下对角元素互为镜像,统称为非对角元素(相反对角元素,在任何相关矩阵中都等于 1,因为任何变量与自身的相关性都只有 1)。

只要下对角线中的第 i 行号和第 j 列号在上对角线中交换,即变量 1 和 2(第 1 行,第 2 列)对于变量 2 和 1(第 2 行,第 1 列)是相同的。因此,我们只需要重新计算下对角线元素,并将其复制到矩阵的上对角线中对应的位置

import numpy as np
from numpy.random import randn
X = randn(20,3)
Rho = np.corrcoef(X.T) #correlation matrix
print(np.tril(Rho)) #lower off-diagonal of matrix Rho to re-calculate, then copy to other side

表演

array([[ 1.        ,  0.        ,  0.        ],
       [-0.03003281,  1.        ,  0.        ],
       [-0.02602238,  0.06137713,  1.        ]])

为以下步骤序列编写“i 不等于 j”循环的最有效方法是什么:

  1. 根据一些 apply 函数重新计算对称矩阵的下非对角线元素(为简单起见,我们只需为这些元素中的每一个添加 +2)
  2. 将相同的计算翻转到其镜像上(对应的上非对角线)
  3. 另外,将对称矩阵的 diagonal 元素替换为填充 10 的向量(而不是相关矩阵中的 1)

目的是生成一个新矩阵,它是对原始矩阵的重新计算。

【问题讨论】:

    标签: python arrays matrix statistics diagonal


    【解决方案1】:

    让我们首先生成Rho(请注意,我正在初始化伪随机数生成器,以便在不同的代码运行中获得相同的Rho):

    In [526]: import numpy as np
    
    In [527]: np.random.seed(0)
         ...: n = 3
         ...: X = np.random.randn(20, n)
         ...: Rho = np.corrcoef(X.T)
    
    In [528]: Rho
    Out[528]: 
    array([[1.        , 0.03224462, 0.05021998],
           [0.03224462, 1.        , 0.15140358],
           [0.05021998, 0.15140358, 1.        ]])
    

    那么就可以使用NumPy的tril_indices_fromadvanced indexing来生成新的矩阵了:

    In [548]: result = np.zeros_like(Rho)
    
    In [549]: lrows, lcols = np.tril_indices_from(Rho, k=-1)
    
    In [550]: result[lrows, lcols] = Rho[lrows, lcols] + 2
    
    In [551]: result
    Out[551]: 
    array([[0.        , 0.        , 0.        ],
           [2.03224462, 0.        , 0.        ],
           [2.05021998, 2.15140358, 0.        ]])
    
    In [552]: result[lcols, lrows] = result[lrows, lcols]
    
    In [553]: result
    Out[553]: 
    array([[0.        , 2.03224462, 2.05021998],
           [2.03224462, 0.        , 2.15140358],
           [2.05021998, 2.15140358, 0.        ]])
    
    In [554]: result[np.arange(n), np.arange(n)] = 10
    
    In [555]: result
    Out[555]: 
    array([[10.        ,  2.03224462,  2.05021998],
           [ 2.03224462, 10.        ,  2.15140358],
           [ 2.05021998,  2.15140358, 10.        ]])
    

    【讨论】:

      猜你喜欢
      • 2023-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-18
      • 2017-04-29
      • 1970-01-01
      相关资源
      最近更新 更多