如何提取非正方形 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.
传递
所以基本上我有一个数组 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.
传递