我在冗余的完整矩阵上进行一些计算(即可以是三角矩阵而不会丢失信息)。我意识到我只能计算三角形的下半部分以获得更快的结果。一旦完成,我怎样才能将下三角形投影到鞋面?
换句话说,我该如何反转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]]
如何将其转换回完整的矩阵?
答案 0 :(得分:7)
假设A
为输入数组,下面列出的方法很少。
方法#1:在np.triu
的转置版本上使用A
-
np.triu(A.T,1) + A
方法#2:避免使用A.T和A之间的直接求和np.triu
,然后建立索引以设置对角线元素 -
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:与上一个相同,但使用布尔索引来设置对角线元素 -
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非常有效!
答案 1 :(得分:1)
由于矩阵是对称的,你可以这样做:
m = np.array([1,1,0,1,1,1,0,1,1]).reshape((3,3))
# after some computation you get x
x = np.tril(m)
m_recomposed = x + x.transpose() - np.diag(np.diag(x))
#array([[1, 1, 0],
# [1, 1, 1],
# [0, 1, 1]])
#In [152]: np.array_equal(m, m_recomposed)
#Out[152]: True