提取numpy矩阵的上三角或下三角部分

112 投票
3 回答
151152 浏览
提问于 2025-04-17 10:30

我有一个矩阵 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.]])

3 个回答

22

使用 数组创建方法 中的 numpy.triunumpy.tril,可以得到一个矩阵的副本,并把第 k 条对角线以上或以下的元素都变成零。

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

要将上三角的值提取到一个平坦的向量中,你可以这样做:

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

同样的,对于下三角,可以使用np.tril


重要提示

如果你想提取对角线以上(或者对角线以下)的值,可以使用k这个参数。这个参数通常在矩阵是对称的时候使用。

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

编辑(2019年11月11日):

如果想把提取出来的向量放回一个二维的对称数组中,可以参考我在这里的回答:https://stackoverflow.com/a/58806626/5025009

105

试试 numpy.triu(上三角)和 numpy.tril(下三角)。

代码示例:

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

撰写回答