Python 对角矩阵数组的矢量化创建,

Python 对角矩阵数组的矢量化创建,,python,numpy,numpy-ndarray,array-broadcasting,Python,Numpy,Numpy Ndarray,Array Broadcasting,我有一个称为对角线的2d数组,其中每一行表示2d矩阵的对角线。创建3d阵列对角线矩阵的最快/最好方法是什么?最后两个维度都由使用对角线行创建的对角线矩阵组成 在循环中,这就是我想要的: import numpy as np diag_matricies = np.zeros([3,3,3]) diagonals = np.array([[1,2,3],[4,5,6],[7,8,9]]) for i in range(3): diag_matricies[i] = np.diag(di

我有一个称为对角线的2d数组,其中每一行表示2d矩阵的对角线。创建3d阵列对角线矩阵的最快/最好方法是什么?最后两个维度都由使用对角线行创建的对角线矩阵组成

在循环中,这就是我想要的:

import numpy as np

diag_matricies = np.zeros([3,3,3])
diagonals = np.array([[1,2,3],[4,5,6],[7,8,9]])

for i in range(3):
    diag_matricies[i] = np.diag(diagonals[i,:]) 

print(diag_matricies)


一个更快的选择是使用:

每个尺寸为1200的计时:

from datetime import datetime
N = 1200
diag_matricies = np.zeros([N, N, N])
diagonals = np.arange(N * N).reshape((N, N))

start = datetime.now()
index = np.arange(N)
diag_matricies[:, index, index] = diagonals
print('advanced indexing: ', datetime.now() - start)

start = datetime.now()
for i in range(N):
    diag_matricies[i] = np.diag(diagonals[i])
print('for loop: ', datetime.now() - start)

# advanced indexing:  0:00:01.537120
# for loop:  0:00:07.281833

一个更快的选择是使用:

每个尺寸为1200的计时:

from datetime import datetime
N = 1200
diag_matricies = np.zeros([N, N, N])
diagonals = np.arange(N * N).reshape((N, N))

start = datetime.now()
index = np.arange(N)
diag_matricies[:, index, index] = diagonals
print('advanced indexing: ', datetime.now() - start)

start = datetime.now()
for i in range(N):
    diag_matricies[i] = np.diag(diagonals[i])
print('for loop: ', datetime.now() - start)

# advanced indexing:  0:00:01.537120
# for loop:  0:00:07.281833

您可以使用
np.einsum

>>> out = np.zeros((3,3,3))
>>> np.einsum('ijj->ij',out)[...] = diagonals
>>> out
array([[[1., 0., 0.],
        [0., 2., 0.],
        [0., 0., 3.]],

       [[4., 0., 0.],
        [0., 5., 0.],
        [0., 0., 6.]],

       [[7., 0., 0.],
        [0., 8., 0.],
        [0., 0., 9.]]])
这在引擎盖下的作用大致如下:

>>> out2 = np.zeros((3,3,3))
>>> out2.reshape(3,9)[:,::4] = diagonals
>>> out2
array([[[1., 0., 0.],
        [0., 2., 0.],
        [0., 0., 3.]],

       [[4., 0., 0.],
        [0., 5., 0.],
        [0., 0., 6.]],

       [[7., 0., 0.],
        [0., 8., 0.],
        [0., 0., 9.]]])

只有
einsum
方法也适用于非连续阵列。

您可以使用
np.einsum

>>> out = np.zeros((3,3,3))
>>> np.einsum('ijj->ij',out)[...] = diagonals
>>> out
array([[[1., 0., 0.],
        [0., 2., 0.],
        [0., 0., 3.]],

       [[4., 0., 0.],
        [0., 5., 0.],
        [0., 0., 6.]],

       [[7., 0., 0.],
        [0., 8., 0.],
        [0., 0., 9.]]])
这在引擎盖下的作用大致如下:

>>> out2 = np.zeros((3,3,3))
>>> out2.reshape(3,9)[:,::4] = diagonals
>>> out2
array([[[1., 0., 0.],
        [0., 2., 0.],
        [0., 0., 3.]],

       [[4., 0., 0.],
        [0., 5., 0.],
        [0., 0., 6.]],

       [[7., 0., 0.],
        [0., 8., 0.],
        [0., 0., 9.]]])
只有
einsum
方法也适用于非连续阵列