提取一个数字矩阵的上三角形或下三角形部分

我有一个矩阵 A,我需要两个矩阵 UL,使得 U包含 A 的上三角形元素(所有上面的元素,不包括对角线) ,同样地,对于 L(所有下面的元素,不包括对角线)。是否有 numpy的方法来做到这一点?

例如:

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.]])
124922 次浏览

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