在this question中,解释了如何访问给定矩阵的lower
和upper
三角形部分,例如:
m = np.matrix([[11, 12, 13],
[21, 22, 23],
[31, 32, 33]])
这里我需要在一维数组中转换矩阵,可以这样做:
indices = np.triu_indices_from(m)
a = np.asarray( m[indices] )[-1]
#array([11, 12, 13, 22, 23, 33])
在使用a
进行大量计算后,更改其值,它将用于填充对称的2D数组:
new = np.zeros(m.shape)
for i,j in enumerate(zip(*indices)):
new[j]=a[i]
new[j[1],j[0]]=a[i]
返回:
array([[ 11., 12., 13.],
[ 12., 22., 23.],
[ 13., 23., 33.]])
有没有更好的方法来实现这一目标?更具体地说,避免Python循环重建2D数组?
答案 0 :(得分:6)
您是否只想形成对称阵列?你可以完全跳过对角线指数。
m=np.array(m)
inds = np.triu_indices_from(m,k=1)
m[(inds[1], inds[0])] = m[inds]
m
array([[11, 12, 13],
[12, 22, 23],
[13, 23, 33]])
从:
创建对称数组new = np.zeros((3,3))
vals = np.array([11, 12, 13, 22, 23, 33])
inds = np.triu_indices_from(new)
new[inds] = vals
new[(inds[1], inds[0])] = vals
new
array([[ 11., 12., 13.],
[ 12., 22., 23.],
[ 13., 23., 33.]])
答案 1 :(得分:3)
您可以使用Array Creation Routines,numpy.triu和numpy.tril等numpy.diag来创建三角形的对称矩阵。这是一个简单的3x3示例。
a = np.array([[1,2,3],[4,5,6],[7,8,9]])
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
a_triu = np.triu(a, k=0)
array([[1, 2, 3],
[0, 5, 6],
[0, 0, 9]])
a_tril = np.tril(a, k=0)
array([[1, 0, 0],
[4, 5, 0],
[7, 8, 9]])
a_diag = np.diag(np.diag(a))
array([[1, 0, 0],
[0, 5, 0],
[0, 0, 9]])
添加转置并减去对角线:
a_sym_triu = a_triu + a_triu.T - a_diag
array([[1, 2, 3],
[2, 5, 6],
[3, 6, 9]])
a_sym_tril = a_tril + a_tril.T - a_diag
array([[1, 4, 7],
[4, 5, 8],
[7, 8, 9]])
答案 2 :(得分:2)
将向量放回2D对称阵列的最快,最聪明的方法是:
情况1:无偏移(k = 0),即上三角部分包含对角线
import numpy as np
X = np.array([[1,2,3],[4,5,6],[7,8,9]])
#array([[1, 2, 3],
# [4, 5, 6],
# [7, 8, 9]])
#get the upper triangular part of this matrix
v = X[np.triu_indices(X.shape[0], k = 0)]
print(v)
# [1 2 3 5 6 9]
# put it back into a 2D symmetric array
size_X = 3
X = np.zeros((size_X,size_X))
X[np.triu_indices(X.shape[0], k = 0)] = v
X = X + X.T - np.diag(np.diag(X))
#array([[1., 2., 3.],
# [2., 5., 6.],
# [3., 6., 9.]])
即使您使用numpy.array
代替numpy.matrix
,上述方法也可以正常工作。
情况2:偏移(k = 1),即上三角部分不包括对角线
import numpy as np
X = np.array([[1,2,3],[4,5,6],[7,8,9]])
#array([[1, 2, 3],
# [4, 5, 6],
# [7, 8, 9]])
#get the upper triangular part of this matrix
v = X[np.triu_indices(X.shape[0], k = 1)] # offset
print(v)
# [2 3 6]
# put it back into a 2D symmetric array
size_X = 3
X = np.zeros((size_X,size_X))
X[np.triu_indices(X.shape[0], k = 1)] = v
X = X + X.T
#array([[0., 2., 3.],
# [2., 0., 6.],
# [3., 6., 0.]])