如何提取非正方形 numpy 数组的 lower/upper 三角形?

How do I extract the lower/upper triangle of a non-square numpy array?

所以基本上我有一个数组 subslope 包含以下内容:

import numpy as np
import matplotlib.pyplot as plt

slp = 1501.66*(np.ones((1000,1000), dtype=np.float32))
vsub = 2000*(np.ones((1000,1000), dtype=np.float32))

slope = np.triu(slp)
slope2 = np.tril(vsub, k=-1)
subslope = slope + slope2

这是视觉表示:

您可以看到将数组的两部分分开的对角线,上面部分的值是 1501.66 和对角线下方的 2000。但是,当我更改尺寸时,列数明显大于这样的行数:

slp = 1501.66*(np.ones((1000,2000), dtype=np.float32))
vsub = 2000*(np.ones((1000,2000), dtype=np.float32))

我们得到以下信息:

我想要的是 运行 从数组的顶角到底角的对角线,如下所示:

我怎样才能做到这一点?

您可以使用 np.indices 创建布尔掩码:

import numpy as np
import matplotlib.pyplot as plt

shape = (1000, 2000)
i,j = np.indices(shape)
m = np.ceil(i <= j*shape[0]/shape[1]).astype(bool)

subslope = np.empty(shape, np.float32)
subslope[m] = 1501.66
subslope[~m] = 2000

plt.imshow(subslope)

要生成您的数组,具有 nR 行和 nC 列,填充:

  • valDiag,
  • 的对角线上
  • 在对角线上 valUpper,
  • 在对角线下方 valLower,

您可以使用以下功能:

def genDiag(nR, nC, valUpper, valDiag, valLower):
    slope = nC / nR
    tbl = np.full((nR, nC), valDiag, dtype=float)
    for r in range(nR):
        tbl[r, 0 : int(round(slope * r, 0))] = valLower
        tbl[r, int(round(slope * (r + 1), 0)) : nC] = valUpper
    return tbl

为了测试它,在较小的数字上,运行:

res = genDiag(8, 14, 15.1, 0, 20.2)
print(res)

结果是:

[[ 0.   0.  15.1 15.1 15.1 15.1 15.1 15.1 15.1 15.1 15.1 15.1 15.1 15.1]
 [20.2 20.2  0.   0.  15.1 15.1 15.1 15.1 15.1 15.1 15.1 15.1 15.1 15.1]
 [20.2 20.2 20.2 20.2  0.  15.1 15.1 15.1 15.1 15.1 15.1 15.1 15.1 15.1]
 [20.2 20.2 20.2 20.2 20.2  0.   0.  15.1 15.1 15.1 15.1 15.1 15.1 15.1]
 [20.2 20.2 20.2 20.2 20.2 20.2 20.2  0.   0.  15.1 15.1 15.1 15.1 15.1]
 [20.2 20.2 20.2 20.2 20.2 20.2 20.2 20.2 20.2  0.  15.1 15.1 15.1 15.1]
 [20.2 20.2 20.2 20.2 20.2 20.2 20.2 20.2 20.2 20.2  0.   0.  15.1 15.1]
 [20.2 20.2 20.2 20.2 20.2 20.2 20.2 20.2 20.2 20.2 20.2 20.2  0.   0. ]]

如果您希望此 table 不单独填充对角线, 先下定决心对角线元素是否要填充 使用“上限”或“下限”值,然后将所选值作为 valDiag.

传递