I have a matrix A and I want 2 matrices U and L such that U contains the upper triangular elements of A (all elements above and not including diagonal) and similarly for L(all elements below and not including diagonal). Is there a numpy method to do this?
e.g
A = array([[ 4., 9., -3.], [ 2., 4., -2.], [-2., -3., 7.]])
U = array([[ 0., 9., -3.], [ 0., 0., -2.], [ 0., 0., 0.]])
L = array([[ 0., 0., 0.], [ 2., 0., 0.], [-2., -3., 0.]]) 3 Answers
Try numpy.triu (triangle-upper) and numpy.tril (triangle-lower).
Code example:
np.triu([[1,2,3],[4,5,6],[7,8,9],[10,11,12]])
array([[ 1, 2, 3], [ 4, 5, 6], [ 0, 8, 9], [ 0, 0, 12]]) 1 To extract the upper triangle values to a flat vector, you can do something like the following:
import numpy as np
a = np.array([[1,2,3],[4,5,6],[7,8,9]])
print(a)
#array([[1, 2, 3],
# [4, 5, 6],
# [7, 8, 9]])
a[np.triu_indices(3)]
#or
list(a[np.triu_indices(3)])
#array([1, 2, 3, 5, 6, 9])Similarly, for the lower triangle, use np.tril.
IMPORTANT
If you want to extract the values that are above the diagonal (or below) then use the k argument. This is usually used when the matrix is symmetric.
import numpy as np
a = np.array([[1,2,3],[4,5,6],[7,8,9]])
#array([[1, 2, 3],
# [4, 5, 6],
# [7, 8, 9]])
a[np.triu_indices(3, k = 1)]
# this returns the following
array([2, 3, 6])EDIT (on 11.11.2019):
To put back the extracted vector into a 2D symmetric array, one can follow my answer here:
1Use the Array Creation Routines of numpy.triu and numpy.tril to return a copy of a matrix with the elements above or below the k-th diagonal zeroed.
>>> a = np.array([[1,2,3],[4,5,6],[7,8,9]]) >>> a array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) >>> tri_upper_diag = np.triu(a, k=0) >>> tri_upper_diag array([[1, 2, 3], [0, 5, 6], [0, 0, 9]]) >>> tri_upper_no_diag = np.triu(a, k=1) >>> tri_upper_no_diag array([[0, 2, 3], [0, 0, 6], [0, 0, 0]]) >>> tri_lower_diag = np.tril(a, k=0) >>> tri_lower_diag array([[1, 0, 0], [4, 5, 0], [7, 8, 9]]) >>> tri_lower_no_diag = np.tril(a, k=-1) >>> tri_lower_no_diag array([[0, 0, 0], [4, 0, 0], [7, 8, 0]]) 1