Copy upper triangle to lower triangle in a python matrix

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

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

Tags:

Python

Matrix