使用numpy清零矩阵的上三角。

5

假设我们有一个n x n的矩阵。以n=4为例:

x x x x
x x x x
x x x x
x x x x

这是我想要实现的目标: 当 cut=1 时,由函数参数给出,矩阵变为:
x x x x
x x x x
x x x x
x x x 0

当cut=3时:

x x x x
x x x 0
x x 0 0
x 0 0 0

当cut=5时:

x x 0 0
x 0 0 0
0 0 0 0
0 0 0 0

如我们所见,对角线像斜杠一样被切开,第一条斜线以下的所有内容都将被清零。
我正在使用numpy的矩阵工具生成矩阵,但我不知道如何编写这样的算法。请帮忙吗?
您可以始终假定此矩阵将是一个n x n矩阵,切割次数小于2n-1。

2
看一下triu。它做了类似的事情,但在不同的角落。您可以在triu之前和之后调整矩阵以获得正确的结果。 - Mathias711
谢谢,@Mathias711。我一读完这个文档就知道我们可以将矩阵旋转到其支持的形式,然后再旋转回来。感谢你们所有人的帮助。 - Luxing
3个回答

5
您可以使用np.tri来生成一个矩阵,其中包含给定对角线下方的1和上方的0。由于您希望右下角为零,因此我们需要左右翻转:
bottom_right = lambda N, k: np.fliplr(np.tri(N, k=k-N)) == 1

例如,bottom_right(4, 2) 创建以下布尔矩阵:
array([[False, False, False, False],
       [False, False, False, False],
       [False, False, False,  True],
       [False, False,  True,  True]], dtype=bool)

你可以使用这个切片来清除角落内容:
a = np.ones((4, 4))
a[bottom_right(4, 2)] = 0

a现在是

array([[ 1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  0.],
       [ 1.,  1.,  0.,  0.]])

另一种方法:

这是基于Mathias711的答案的一行代码:

f = lambda a, k: np.fliplr(np.triu(np.fliplr(a), k=k-a.shape[0]+1))

3
每当你不必要地使用 lambda 来编写函数时,Guido 就会杀掉一只小猫咪。 - Jaime

3
a = np.array(range(16)).reshape((4,4))
b = np.array([list(i[::-1]) for i in a])
b = np.triu(b,-2)
b = np.array([list(i[::-1]) for i in b])
print b

产生:

array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14,  0]])

因此,triu 中的 -2 对应于问题中所需的 1。请确保执行此操作的函数能够纠正此效果。我知道这并不是你遇到的最 Pythonic 的代码,但它能解决问题。

3

You can use following simple function :

>>> def convertor(cut,array):
...     return np.flipud(np.tri(4,4,3-cut)).__mul__(array)

在这个函数中,我创建了一个与您的矩阵具有相同维度的矩阵,使用了 np.trinp.flipud 函数。但是,根据您想要的结果,它由 0 和 1 组成。例如,对于 cut = 2,您将得到以下结果:
>>> np.flipud(np.tri(4,4,3-2))
array([[ 1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  0.],
       [ 1.,  1.,  0.,  0.]])

现在,您需要将此矩阵与我们在函数内返回的矩阵相乘!

演示:

>>> m=array([[ 4.,  4.,  4.,  4.],
...          [ 4.,  4.,  4.,  4.],
...          [ 4.,  4.,  4.,  4.],
...          [ 4.,  4.,  4.,  4.]])
>>> convertor(3,m)
array([[ 4.,  4.,  4.,  4.],
       [ 4.,  4.,  4.,  0.],
       [ 4.,  4.,  0.,  0.],
       [ 4.,  0.,  0.,  0.]])
>>> convertor(0,m)
array([[ 4.,  4.,  4.,  4.],
       [ 4.,  4.,  4.,  4.],
       [ 4.,  4.,  4.,  4.],
       [ 4.,  4.,  4.,  4.]])
>>> convertor(1,m)
array([[ 4.,  4.,  4.,  4.],
       [ 4.,  4.,  4.,  4.],
       [ 4.,  4.,  4.,  4.],
       [ 4.,  4.,  4.,  0.]])
>>> convertor(5,m)
array([[ 4.,  4.,  0.,  0.],
       [ 4.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.]])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接