我正在寻找一种有效的方法(最好是矢量化快速内置函数)来按对角线顺序展平numpy数组。例如:
A=np.array([[1,2,3],
[4,5,6],
[7,8,9]])
b=flatten_diagonally(A)
b
应为[7,4,8,1,5,9,2,6,3]
。
A
将是一个非常大的矩阵,因此我不想单独迭代这些元素。出于同样的原因,我也不想提前准备好所有指数的清单。由于A
很大且结果同样大,我想避免使用大量内存的解决方案。
如果我可以指定我想要展平哪个对角线子集会更好,例如仅展平第1和第2对角线将给出[1,5,9,2,6]
。
答案 0 :(得分:0)
numpy.diag沿某个索引返回对角线。 Documentation
所以这应该给你想要的输出:(注意第0个对角线是正常的对角线,所以如果你想要对角线,你可能需要使用对角线的负值。)
import numpy as np
def flatten_diagonally(npA, diagonals = None):
diagonals = diagonals or xrange(-npA.shape[0] + 1, npA.shape[1])
return np.concatenate(map(lambda x: np.diag(npA, k = x), diagonals))
请注意,您可以使用np.diagonal而不是np.diag,我不太确定哪种方法更好。 Documentation
答案 1 :(得分:0)
以下函数基于indices
比较,基于每个对角线具有索引关系的事实,例如在主对角线i==j
,等等......
即使对于非平方2D阵列也是有效的。
def flatten_diagonally(x, diags=None):
diags = np.array(diags)
if x.shape[1] > x.shape[0]:
diags += x.shape[1]-x.shape[0]
n = max(x.shape)
ndiags = 2*n-1
i,j = np.indices(x.shape)
d = np.array([])
for ndi in range(ndiags):
if diags != None:
if not ndi in diags:
continue
d = np.concatenate((d,x[i==j+(n-1)-ndi]))
return d
示例:
print flatten_diagonally(A)
#[ 7. 4. 8. 1. 5. 9. 2. 6. 3.]
print flatten_diagonally(A, diags=(1,2))
#[ 4. 8. 1. 5. 9.]
对于非平方数组:
A=np.array([[1,2,3],
[7,8,9]])
print flatten_diagonally(A, diags=(1,2))
#[ 1. 8. 2. 9.]