沿数组对角线包装/解包向量

5

我一直在寻找一种更高效的方法(而不是只写循环遍历矩阵)来根据包装对角线顺序中给定的元素创建矩阵,并以此顺序提取值。例如,给定a = [2,3,4,5,6,7],我希望能够生成数组

[  0,  2,  5,  7,
   0,  0,  3,  6,
   0,  0,  0,  4,
   0,  0,  0,  0]

还需要能够从该数组中重新提取a

scipy.sparse.diags实现了类似于这样的功能,但正如其名称所示,它是针对稀疏数组而设计的。numpy中是否有任何提供此功能或某种形式的基于对角线的索引的功能?或者可能有一些类型的数组转换可以使这更可行吗?


你的数组是一维数组是有意为之吗? - askewchan
3个回答

5

按照Josh Adel提出的方法,如果您想按对角线而非行来保持数据排序,只需稍微调整np.triu_indices的返回值即可构建自己的索引生成程序:

def my_triu_indices(n, k=0):
    rows, cols = np.triu_indices(n, k)
    rows = cols - rows - k
    return rows, cols

现在你可以做:

>>> a = np.array([2,3,4,5,6,7])
>>> b = np.zeros((4, 4), dtype=a.dtype)
>>> b[my_triu_indices(4, 1)] = a
>>> b
array([[0, 2, 5, 7],
       [0, 0, 3, 6],
       [0, 0, 0, 4],
       [0, 0, 0, 0]])
>>> b[my_triu_indices(4, 1)]
array([2, 3, 4, 5, 6, 7])

+1 很棒。我知道有一个简单的方法可以重新排列,但是没有时间深入研究。很高兴你发布了解决方案。 - JoshAdel

3

如果你愿意以略微不同的方式订购a,你可以做如下操作:

import numpy as np
a = [2,5,7,3,6,4]
b = np.zeros((4,4))
b[np.triu_indices(4,1)] = a
In [11]: b
Out[11]:
array([[ 0.,  2.,  5.,  7.],
       [ 0.,  0.,  3.,  6.],
       [ 0.,  0.,  0.,  4.],
       [ 0.,  0.,  0.,  0.]])

然后您可以通过以下方式提取这些值:

In [23]: b[np.triu_indices(4,1)]
Out[23]: array([ 2.,  5.,  7.,  3.,  6.,  4.])

2

这并不是直接的方法,但应该能够实现。如果我们分解一下Numpy如何找出对角线索引,我们可以重新构建它以得到您想要的结果。

def get_diag_indices(s,k):
    n = s
    if (k >= 0):
        i = np.arange(0,n-k)
        fi = i+k+i*n
    else:
        i = np.arange(0,n+k)
        fi = i+(i-k)*n
    return fi

indices=np.hstack(([get_diag_indices(4,1+x) for x in range(3)]))
a=np.array([2, 3, 4, 5, 6, 7])
out=np.zeros((4,4))

>>> out.flat[indices]=a
>>> out
array([[ 0.,  2.,  5.,  7.],
       [ 0.,  0.,  3.,  6.],
       [ 0.,  0.,  0.,  4.],
       [ 0.,  0.,  0.,  0.]])

>>> out.flat[indices]
array([ 2.,  3.,  4.,  5.,  6.,  7.])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接