我有一个矩阵:
[
[ 5 10 15 20]
[ 6 12 18 24]
[ 7 14 21 28]
[ 8 16 24 32]
]
是(4x4)。
我想制作一个(4x4x4)矩阵,如下所示:
[
[
[ 5 0 0 0]
[ 6 0 0 0]
[ 7 0 0 0]
[ 8 0 0 0]]
[
[ 0 10 0 0]
[ 0 12 0 0]
[ 0 14 0 0]
[ 0 16 0 0]]
[
[ 0 0 15 0]
[ 0 0 18 0]
[ 0 0 21 0]
[ 0 0 24 0]]
[
[ 0 0 0 20]
[ 0 0 0 24]
[ 0 0 0 28]
[ 0 0 0 32]]
]
以矩阵方式执行此操作的最佳方法是什么(不使用for循环)?
答案 0 :(得分:7)
您可以通过将对角线阵列与额外轴相乘来实现:
>>> a = np.arange(16).reshape(4,4)
>>> a
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
>>> a*np.eye(4)[:,np.newaxis]
array([[[ 0., 0., 0., 0.],
[ 4., 0., 0., 0.],
[ 8., 0., 0., 0.],
[ 12., 0., 0., 0.]],
[[ 0., 1., 0., 0.],
[ 0., 5., 0., 0.],
[ 0., 9., 0., 0.],
[ 0., 13., 0., 0.]],
[[ 0., 0., 2., 0.],
[ 0., 0., 6., 0.],
[ 0., 0., 10., 0.],
[ 0., 0., 14., 0.]],
[[ 0., 0., 0., 3.],
[ 0., 0., 0., 7.],
[ 0., 0., 0., 11.],
[ 0., 0., 0., 15.]]])
答案 1 :(得分:4)
您可以使用所需的形状创建一个零数组,然后使用简单的索引来填充数组列中的预期索引:
x, y = a.shape
arr = np.zeros((x, y, y))
ind = np.arange(y)
arr[ind,:,ind] = a.T
演示:
In [40]: a = np.array([
...: [ 5 ,10 ,15, 20],
...: [ 6, 12, 18, 24],
...: [ 7, 14, 21, 28],
...: [ 8, 16, 24, 32]
...: ])
In [43]: arr[np.arange(4),:,np.arange(4)] = a.T
In [44]: arr
Out[44]:
array([[[ 5., 0., 0., 0.],
[ 6., 0., 0., 0.],
[ 7., 0., 0., 0.],
[ 8., 0., 0., 0.]],
[[ 0., 10., 0., 0.],
[ 0., 12., 0., 0.],
[ 0., 14., 0., 0.],
[ 0., 16., 0., 0.]],
[[ 0., 0., 15., 0.],
[ 0., 0., 18., 0.],
[ 0., 0., 21., 0.],
[ 0., 0., 24., 0.]],
[[ 0., 0., 0., 20.],
[ 0., 0., 0., 24.],
[ 0., 0., 0., 28.],
[ 0., 0., 0., 32.]]])
使用np.eye()
进行其他答案的基准测试,乘法和广播表明此答案的速度提高了一倍。
In [46]: def use_zeros(arr):
...: x, y = arr.shape
...: z = np.zeros((x, y, y))
...: ind = np.arange(y)
...: z[ind,:,ind] = a.T
...: return z
...:
...:
In [47]: def use_eye(arr):
...: return arr*np.eye(arr.shape[1])[:,np.newaxis]
...:
...:
In [48]: a = np.arange(10000).reshape(100,100)
In [49]: %timeit use_zeros(a)
1.23 ms ± 14.8 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
In [50]: %timeit use_eye(a)
2.47 ms ± 23.4 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)