提取numpy矩阵的上三角或下三角部分
我有一个矩阵 A
,我想要得到两个矩阵 U
和 L
,其中 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.triu 和 numpy.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]])