我一直在寻找一种方法(更有效的方法就是编写循环遍历矩阵)从包装对角线顺序给出的元素创建矩阵,并按此顺序提取值。举个例子,给定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中是否有任何类型的功能可以提供此功能,或者某种形式的基于对角线的索引?或者某些类型的数组转换会使这更可行?
答案 0 :(得分: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 :(得分: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 :(得分: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.])