假设你有两个数组:
index = [1, 2, 3]
counts = [2, 3, 2]
或一个单一的数组
arr = [1, 1, 2, 2, 2, 3, 3]
我该如何高效构建这个矩阵
[
[1, 1, 0, 0, 0, 0, 0],
[1, 1, 0, 0, 0, 0, 0],
[0, 0, 2, 2, 2, 0, 0],
[0, 0, 2, 2, 2, 0, 0],
[0, 0, 2, 2, 2, 0, 0],
[0, 0, 0, 0, 0, 3, 3],
[0, 0, 0, 0, 0, 3, 3]
]
使用NumPy吗?
我知道
square = np.zeros((7, 7))
np.fill_diagnol(square, arr) # see arr above
产生
[
[1, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 0],
[0, 0, 2, 0, 0, 0, 0],
[0, 0, 0, 2, 0, 0, 0],
[0, 0, 0, 0, 2, 0, 0],
[0, 0, 0, 0, 0, 3, 0],
[0, 0, 0, 0, 0, 0, 3]
]
如何通过n
来“扩展”对角线,其中n
是由index[I]
指定的值的counts[index-1]
tmp = np.array((arr * N)).reshape((len(arr), len(arr))
np.floor( (tmp + tmp.T) / 2 ) # <-- this is closer
array([[1., 1., 1., 1., 1., 2., 2.],
[1., 1., 1., 1., 1., 2., 2.],
[1., 1., 2., 2., 2., 2., 2.],
[1., 1., 2., 2., 2., 2., 2.],
[1., 1., 2., 2., 2., 2., 2.],
[2., 2., 2., 2., 2., 3., 3.],
[2., 2., 2., 2., 2., 3., 3.]])
这可以得到我想要的,但可能扩展性不太好?
riffled = list(zip(index, counts))
riffled
# [(1, 2), (2, 3), (3, 2)]
a = np.zeros((len(arr), len(arr))) # 7, 7 square
last = 0 # <-- keep track of current sub square
for i, c in riffled:
a[last:last+c, last:last+c] = np.ones((c, c)) * i
last += c # <-- shift square
产量
array([[1., 1., 0., 0., 0., 0., 0.],
[1., 1., 0., 0., 0., 0., 0.],
[0., 0., 2., 2., 2., 0., 0.],
[0., 0., 2., 2., 2., 0., 0.],
[0., 0., 2., 2., 2., 0., 0.],
[0., 0., 0., 0., 0., 3., 3.],
[0., 0., 0., 0., 0., 3., 3.]])
np.equal.outer(arr, arr) * arr
- user3483203