Extract upper or lower triangular part of a numpy matrix

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

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

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

Method 2

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

Method 3

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


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x