简体   繁体   English

如何从矩阵中选择特定的非对角带?

[英]How to select a specific off-diagonal band from a matrix?

Suppose an NxN square matrix.假设一个NxN方阵。 I would like to select a band of width w which is offset by k to the main diagonal as shown in the following example for N = 9, w = 4, k = -1我想选择一个宽度为w的带,它与主对角线偏移k ,如下面的示例所示, N = 9, w = 4, k = -1

在此处输入图片说明

The ordering of elements should be as for np.tril_indices(N, k=k) .元素的顺序应该与np.tril_indices(N, k=k) So basically the corresponding indices should be np.tril_indices(N, k=k) reduced by np.tril_indices(N, k=kw) :所以基本上相应的索引应该是np.tril_indices(N, k=k)减去np.tril_indices(N, k=kw)

i1 = list(zip(*np.tril_indices(N, k=k)))
i2 = list(zip(*np.tril_indices(N, k=k-w)))
indices = tuple(zip(*[i for i in i1 if i not in i2]))
M[indices]

Or alternatively using np.tril which however stores the full matrix as an intermediary result and only works for 2D arrays:或者也可以使用np.tril ,但它会将完整矩阵存储为中间结果,并且仅适用于 2D 数组:

B = np.ravel(np.tril(M, k=k) - np.tril(M, k=k-w))
B[B.nonzero()]

I'm wondering whether there is a more effective and/or more concise way to achieve this?我想知道是否有更有效和/或更简洁的方法来实现这一目标?

In [19]: np.tri(6,6, dtype=bool)
Out[19]: 
array([[ True, False, False, False, False, False],
       [ True,  True, False, False, False, False],
       [ True,  True,  True, False, False, False],
       [ True,  True,  True,  True, False, False],
       [ True,  True,  True,  True,  True, False],
       [ True,  True,  True,  True,  True,  True]])

Combining 2 tri masks:结合 2 个tri面罩:

In [22]: np.tri(6,6, dtype=bool)&~np.tri(6,6,-3,dtype=bool)
Out[22]: 
array([[ True, False, False, False, False, False],
       [ True,  True, False, False, False, False],
       [ True,  True,  True, False, False, False],
       [False,  True,  True,  True, False, False],
       [False, False,  True,  True,  True, False],
       [False, False, False,  True,  True,  True]])

In [23]: np.where(Out[22])
Out[23]: 
(array([0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5]),
 array([0, 0, 1, 0, 1, 2, 1, 2, 3, 2, 3, 4, 3, 4, 5]))

np.tri is essentially: np.tri本质上是:

In [29]: np.greater_equal.outer(np.arange(4),np.arange(4))
Out[29]: 
array([[ True, False, False, False],
       [ True,  True, False, False],
       [ True,  True,  True, False],
       [ True,  True,  True,  True]])
In [30]: np.greater_equal(np.arange(4)[:,None],np.arange(4))
Out[30]: 
array([[ True, False, False, False],
       [ True,  True, False, False],
       [ True,  True,  True, False],
       [ True,  True,  True,  True]])

np.tril just applies where to this. np.tril只适用于where了这一点。

In [37]: np.greater_equal(np.arange(4)[:,None], np.arange(4)) & 
         np.less_equal(np.arange(-1,3)[:,None], np.arange(4))
Out[37]: 
array([[ True, False, False, False],
       [ True,  True, False, False],
       [False,  True,  True, False],
       [False, False,  True,  True]])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM