将Python矩阵的上三角复制到下三角

50
       iluropoda_melanoleuca  bos_taurus  callithrix_jacchus  canis_familiaris
ailuropoda_melanoleuca     0        84.6                97.4                44
bos_taurus                 0           0                97.4              84.6
callithrix_jacchus         0           0                   0              97.4
canis_familiaris           0           0                   0                 0

这是我拥有的Python矩阵的简短版本。我拥有上三角的信息。是否有一种简单的函数可以将上三角复制到矩阵的下三角?

6个回答

71
要在 NumPy 中实现此操作,而不使用双重循环,可以使用tril_indices。请注意,根据矩阵大小,这可能比添加转置并减去对角线更慢,不过这种方法可能更易读。
>>> i_lower = np.tril_indices(n, -1)
>>> matrix[i_lower] = matrix.T[i_lower]  # make the matrix symmetric

请注意不要混淆tril_indicestriu_indices,因为它们都使用行优先索引,即以下操作无法实现:

>>> i_upper = np.triu_indices(n, 1)
>>> i_lower = np.tril_indices(n, -1)
>>> matrix[i_lower] = matrix[i_upper]  # make the matrix symmetric
>>> np.allclose(matrix.T, matrix)
False

46
最简单且最快(无循环)处理NumPy数组的方法如下:
以下方法对于100x100矩阵比被接受的回答快约3倍,对于10x10矩阵速度大致相同。
import numpy as np

X= np.array([[0., 2., 3.],
             [0., 0., 6.],
             [0., 0., 0.]])

X = X + X.T - np.diag(np.diag(X))
print(X)

#array([[0., 2., 3.],
#       [2., 0., 6.],
#       [3., 6., 0.]])

请注意,矩阵必须要么一开始就是上三角形的,要么可以按以下方法变成上三角形。

rng = np.random.RandomState(123)
X = rng.randomint(10, size=(3, 3))
print(X)
#array([[2, 2, 6],
#       [1, 3, 9],
#       [6, 1, 0]])

X = np.triu(X)
X = X + X.T - np.diag(np.diag(X))
print(X)
#array([[2, 2, 6],
#       [2, 3, 9],
#       [6, 9, 0]])


9
是的,对于大矩阵来说,这个方法是有效且更快的。对于100x100的矩阵,速度提升了3到4倍,但对于10x10的矩阵,时间相同。需要注意的是,这只适用于矩阵的下半部分都是零的情况(就像OP的问题中一样)。如果由于某些原因矩阵的下半部分不全为零,则需要在添加转置和减去对角线之前包含 X = np.triu(X),在此情况下,对于10x10的矩阵速度变慢了约2倍,但对于100x100的矩阵仍然快了约1.5倍。 - Steven C. Howell
嗨@seralouk,如果您能在此帖子中提供一些建议,我们将不胜感激:https://stackoverflow.com/q/65051653/6446053 - mpx

7
如果我正确理解了问题,我相信这个方法可以解决。
for i in range(num_rows):
    for j in range(i, num_cols):
        matrix[j][i] = matrix[i][j]

3

这是一个更好的版本,我猜:

>>> a = np.arange(16).reshape(4, 4)
>>> print(a)
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15]])

>>> iu = np.triu_indices(4,1)
>>> il = (iu[1],iu[0])
>>> a[il]=a[iu]
>>> a
    array([[ 0,  1,  2,  3],
           [ 1,  5,  6,  7],
           [ 2,  6, 10, 11],
           [ 3,  7, 11, 15]])

3
如果 U 是一个上三角矩阵,您可以使用 triu 和转置使其对称:
LDU = triu(U,1)+U.T

0
def inmatrix(m,n):#input Matrix Function 
    a=[]

    for i in range(m):

        b=[]

        for j in range(n):

            elm=int(input("Enter number in Pocket ["+str(i)+"]["+str(j)+"] "))

            b.append(elm)

        a.append(b)

    return  a

def Matrix(a):#print Matrix Function

    for i in range(len(a)):

        for j in range(len(a[0])):

            print(a[i][j],end=" ")

        print()
m=int(input("Enter number of row "))

n=int(input("Enter number of column"))

a=inmatrix(m,n) #call input Matrix function

Matrix(a)#print Matrix 

t=[]#create Blank list 

for i in range(m):

    for j in range(n):

        if i>j:#check upper triangular Elements 

            t.append(a[i][j])#add them in a list 

k=0#variable for list 

for i in range(m):

    for j in range(n):

        if i<j:

            a[i][j]=t[k]copy list item to lower triangular 

            k=k+1

Matrix(a)# print Matrix after change 

稳定,但显然不是numpy的方式。 - AdamHommer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接