Numpy中的矩阵乘法(将2d转换为3d)

SN7*_*N77 2 python numpy matrix

我有一个矩阵:

[
 [ 5 10 15 20]
 [ 6 12 18 24]
 [ 7 14 21 28]
 [ 8 16 24 32]
]
Run Code Online (Sandbox Code Playgroud)

这是(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]]
]
Run Code Online (Sandbox Code Playgroud)

以矩阵方式执行此操作的最佳方法是什么(不使用for循环)?

use*_*424 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.]]])
Run Code Online (Sandbox Code Playgroud)


Kas*_*mvd 5

您可以创建具有所需形状的零数组,然后使用简单的索引用数组的列填充预期索引:

\n\n
x, y = a.shape\narr = np.zeros((x, y, y))\nind = np.arange(y)\narr[ind,:,ind] = a.T\n
Run Code Online (Sandbox Code Playgroud)\n\n

演示:

\n\n
In [40]: a = np.array([\n    ...:  [ 5 ,10 ,15, 20],\n    ...:  [ 6, 12, 18, 24],\n    ...:  [ 7, 14, 21, 28],\n    ...:  [ 8, 16, 24, 32]\n    ...: ])\n\nIn [43]: arr[np.arange(4),:,np.arange(4)] = a.T\n\nIn [44]: arr\nOut[44]: \narray([[[ 5.,  0.,  0.,  0.],\n        [ 6.,  0.,  0.,  0.],\n        [ 7.,  0.,  0.,  0.],\n        [ 8.,  0.,  0.,  0.]],\n\n       [[ 0., 10.,  0.,  0.],\n        [ 0., 12.,  0.,  0.],\n        [ 0., 14.,  0.,  0.],\n        [ 0., 16.,  0.,  0.]],\n\n       [[ 0.,  0., 15.,  0.],\n        [ 0.,  0., 18.,  0.],\n        [ 0.,  0., 21.,  0.],\n        [ 0.,  0., 24.,  0.]],\n\n       [[ 0.,  0.,  0., 20.],\n        [ 0.,  0.,  0., 24.],\n        [ 0.,  0.,  0., 28.],\n        [ 0.,  0.,  0., 32.]]])\n
Run Code Online (Sandbox Code Playgroud)\n\n

使用 、乘法和广播的其他答案的基准测试np.eye()表明,该答案的速度是原来的两倍。

\n\n
In [46]: def use_zeros(arr):\n    ...:     x, y = arr.shape\n    ...:     z = np.zeros((x, y, y))\n    ...:     ind = np.arange(y)\n    ...:     z[ind,:,ind] = a.T\n    ...:     return z\n    ...: \n    ...: \n\nIn [47]: def use_eye(arr):\n    ...:     return arr*np.eye(arr.shape[1])[:,np.newaxis]\n    ...: \n    ...: \n\nIn [48]: a = np.arange(10000).reshape(100,100)\n\nIn [49]: %timeit use_zeros(a)\n1.23 ms \xc2\xb1 14.8 \xc2\xb5s per loop (mean \xc2\xb1 std. dev. of 7 runs, 1000 loops each)\n\nIn [50]: %timeit use_eye(a)\n2.47 ms \xc2\xb1 23.4 \xc2\xb5s per loop (mean \xc2\xb1 std. dev. of 7 runs, 100 loops each)\n
Run Code Online (Sandbox Code Playgroud)\n

  • 是的,确实如此 - “眼睛”解决方案也很好,但像这样就地设置速度更快,内存效率更高。 (2认同)