# Extract upper or lower triangular part of a numpy matrix

## Question:

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

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

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

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: https://stackoverflow.com/a/58806626/5025009

Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.