Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Copy upper triangle to lower triangle in a python matrix

Tags:

python

matrix

       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

This is a short version of the python matrix I have. I have the information in the upper triangle. Is there an easy function to copy the upper triangle to the down triangle of the matrix?

like image 399
biojl Avatar asked May 08 '13 15:05

biojl


People also ask

How do you extract upper triangular matrix in python?

Python NumPy triu() is an inbuilt function that is used to return a copy of the array matrix with an element of the upper part of the triangle with respect to k.

How do you turn a matrix into a lower triangular matrix?

If rows = cols, traverse the array a using two loops where outer loop represents the rows, and inner loop represents the columns of the array a. To convert given matrix to lower triangular matrix, set the elements of the array to 0 where (j > i) that is, the column number is greater than row number.

What is upper triangular matrix and lower triangular matrix in python?

Lower triangular matrix is a matrix which contains elements below principle diagonal including principle diagonal elements and rest of the elements are 0. Upper triangular matrix is a matrix which contains elements above principle diagonal including principle diagonal elements and rest of the elements are 0.


5 Answers

To do this in NumPy, without using a double loop, you can use tril_indices. Note that depending on your matrix size, this may be slower that adding the transpose and subtracting the diagonal though perhaps this method is more readable.

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

Be careful that you do not try to mix tril_indices and triu_indices as they both use row major indexing, i.e., this does not work:

>>> 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
like image 174
Steven C. Howell Avatar answered Oct 18 '22 23:10

Steven C. Howell


The easiest AND FASTEST (no loop) way to do this for NumPy arrays is the following:

The following is ~3x faster for 100x100 matrices compared to the accepted answer and roughly the same speed for 10x10 matrices.

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.]])

Note that the matrix must either be upper triangular to begin with or it should be made upper triangular as follows.

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]])

like image 25
seralouk Avatar answered Oct 19 '22 01:10

seralouk


If I understand the question correctly, I believe this will work

for i in range(num_rows):
    for j in range(i, num_cols):
        matrix[j][i] = matrix[i][j]
like image 6
A.E. Drew Avatar answered Oct 19 '22 00:10

A.E. Drew


Heres a better one i guess :

>>> 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]])
like image 3
Satyam Avatar answered Oct 18 '22 23:10

Satyam


If U is an upper triangular matrix, you can use triu and transpose to make it symmetric:

LDU = triu(U,1)+U.T
like image 2
Yelrew Avatar answered Oct 18 '22 23:10

Yelrew