如何有效地将元素分配到3d矩阵的对角线?

时间:2018-02-05 23:41:01

标签: python numpy matrix scipy diagonal

set.seed(2017);
df <- cbind.data.frame(a = factor(sample(letters, 20, replace = T)), runif(20), rnorm(20));

我想将数组a=np.zeros((3,3,3)) b=np.arange(3) c=np.arange(9).reshape(3,3) b的元素放在3d矩阵(张量)c的对角线(或对角线上方/下方)相对于特定的元素轴。

我累了a,但它只适用于2d矩阵。

例如,如何制作以下矩阵?

numpy.diagflat

2 个答案:

答案 0 :(得分:4)

对于主要对角线,您可以使用np.einsum。例如:

>> np.einsum('iii->i', a)[...] = b
>>> a
array([[[ 0.,  0.,  0.],
        [ 0.,  0.,  0.],
        [ 0.,  0.,  0.]],

       [[ 0.,  0.,  0.],
        [ 0.,  1.,  0.],
        [ 0.,  0.,  0.]],

       [[ 0.,  0.,  0.],
        [ 0.,  0.,  0.],
        [ 0.,  0.,  2.]]])

或者:

>>> np.einsum('iji->ji', a)[...] = c
>>> a
array([[[ 0.,  0.,  0.],
        [ 3.,  0.,  0.],
        [ 6.,  0.,  0.]],

       [[ 0.,  1.,  0.],
        [ 0.,  4.,  0.],
        [ 0.,  7.,  0.]],

       [[ 0.,  0.,  2.],
        [ 0.,  0.,  5.],
        [ 0.,  0.,  8.]]])

编辑:广播正常工作:

>>> np.einsum('ijj->ij', a)[...] = b
>>> a
array([[[ 0.,  0.,  0.],
        [ 0.,  1.,  0.],
        [ 0.,  0.,  2.]],

       [[ 0.,  0.,  0.],
        [ 0.,  1.,  0.],
        [ 0.,  0.,  2.]],

       [[ 0.,  0.,  0.],
        [ 0.,  1.,  0.],
        [ 0.,  0.,  2.]]])

Subdiagonals也可以工作但是因为需要一些手动切片而更加棘手。例如:

>>> a=np.zeros((3,3,3))
>>> np.einsum('iij->ij', a[:2,1:])[...] = c[1:]
>>> a
array([[[ 0.,  0.,  0.],
        [ 3.,  4.,  5.],
        [ 0.,  0.,  0.]],

       [[ 0.,  0.,  0.],
        [ 0.,  0.,  0.],
        [ 6.,  7.,  8.]],

       [[ 0.,  0.,  0.],
        [ 0.,  0.,  0.],
        [ 0.,  0.,  0.]]])

答案 1 :(得分:0)

如果稀疏矩阵满足您的需求,以下是一些资源:

sparse 3d matrix/array in Python?

enter image description here