python - 如何在 NumPy 中将三角矩阵转换为正方形?

标签 python arrays numpy matrix linear-algebra

我正在对一个冗余的完整矩阵进行一些计算(即可以是一个不丢失信息的三角矩阵)。我意识到我只能计算三角形的下部以获得更快的结果。完成后如何将下三角投影到上三角?

换句话说,如何反转np.tril方法?

print DF_var.as_matrix()
# [[1 1 0 1 1 1 0 1 0 0 0]
#  [1 1 1 1 1 0 1 0 1 1 1]
#  [0 1 1 0 0 0 0 0 0 0 0]
#  [1 1 0 1 0 0 0 0 0 0 0]
#  [1 1 0 0 1 0 0 0 0 0 0]
#  [1 0 0 0 0 1 1 0 0 0 0]
#  [0 1 0 0 0 1 1 0 0 0 0]
#  [1 0 0 0 0 0 0 1 1 0 0]
#  [0 1 0 0 0 0 0 1 1 0 0]
#  [0 1 0 0 0 0 0 0 0 1 0]
#  [0 1 0 0 0 0 0 0 0 0 1]]
print np.tril(DF_var.as_matrix())
# [[1 0 0 0 0 0 0 0 0 0 0]
#  [1 1 0 0 0 0 0 0 0 0 0]
#  [0 1 1 0 0 0 0 0 0 0 0]
#  [1 1 0 1 0 0 0 0 0 0 0]
#  [1 1 0 0 1 0 0 0 0 0 0]
#  [1 0 0 0 0 1 0 0 0 0 0]
#  [0 1 0 0 0 1 1 0 0 0 0]
#  [1 0 0 0 0 0 0 1 0 0 0]
#  [0 1 0 0 0 0 0 1 1 0 0]
#  [0 1 0 0 0 0 0 0 0 1 0]
#  [0 1 0 0 0 0 0 0 0 0 1]]

如何将其转换回完整矩阵?

最佳答案

假设A作为输入数组,下面列出了几个方法。

方法 #1:A 的转置版本上使用 np.triu -

np.triu(A.T,1) + A

方法 #2: 避免 np.triu 在 A.T 和 A 之间直接求和,然后索引以设置对角线元素 -

out = A.T + A
idx = np.arange(A.shape[0])
out[idx,idx] = A[idx,idx]

方法 #3: 与上一个相同,但使用内置索引的紧凑型 -

out = A.T + A
np.fill_diagonal(out,np.diag(A))

方法 #4: 与上一个相同,但使用 bool 索引来设置对角线元素 -

out = A.T + A
mask = np.eye(out.shape[0],dtype=bool)
out[mask] = A[mask]

方法 #5: 使用基于掩码的选择对角线元素与 np.where -

np.where(np.eye(A.shape[0],dtype=bool),A,A.T+A)

方法 #6: 使用 np.where -

对所有元素使用基于掩码的选择
np.where(np.triu(np.ones(A.shape[0],dtype=bool),1),A.T,A)

运行时测试

函数-

def func1(A):
    return np.triu(A.T,1) + A

def func2(A):
    out = A.T + A
    idx = np.arange(A.shape[0])
    out[idx,idx] = A[idx,idx]
    return out

def func3(A):
    out = A.T + A
    np.fill_diagonal(out,np.diag(A))
    return out

def func4(A):
    out = A.T + A
    mask = np.eye(out.shape[0],dtype=bool)
    out[mask] = A[mask]
    return out

def func5(A):
    return np.where(np.eye(A.shape[0],dtype=bool),A,A.T+A)

def func6(A):
    return np.where(np.triu(np.ones(A.shape[0],dtype=bool),1),A.T,A)

时间 -

In [140]: # Input array
     ...: N = 5000
     ...: A = np.tril(np.random.randint(0,9,(N,N)))
     ...: 

In [141]: %timeit func1(A)
     ...: %timeit func2(A)
     ...: %timeit func3(A)
     ...: %timeit func4(A)
     ...: %timeit func5(A)
     ...: %timeit func6(A)
     ...: 
1 loops, best of 3: 617 ms per loop
1 loops, best of 3: 354 ms per loop
1 loops, best of 3: 354 ms per loop
1 loops, best of 3: 395 ms per loop
1 loops, best of 3: 597 ms per loop
1 loops, best of 3: 440 ms per loop

看起来方法 #2 和 #3 非常有效!

关于python - 如何在 NumPy 中将三角矩阵转换为正方形?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36250729/

相关文章:

python - 使用 Python 将 XML 模式定义解析为 CSV

c - C中指针数组的问题

c++ - 函数之间的数组指针丢失值(用 swig 编译以在 python3 中使用)

python - Pybrains 迷宫教程出错

python - 从文件中读取字符串的特定区域

python - 将 2 列数据框转换为多级分层数据框

java - 声明了静态数组但方法无法工作

python - SciPy 1D 高斯拟合

python - 来自 ndarray.shape 的奇怪输出

python - 如何获取文件中的 Unix 时间戳?