3

我正在寻找一种有效的方法(最好是矢量化快速内置函数)以对角线顺序展平 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,5,9,2,6].

4

2 回答 2

0

numpy.diag 返回沿某个索引的对角线。文档

所以这应该会给你想要的输出:(注意第 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,我不太确定哪个效果更好。文档

于 2013-05-31T21:42:00.150 回答
0

以下函数基于indices比较,基于每个对角线具有索引关系的事实,例如在主对角线处i==j,等等......

即使对于非平方二维数组也是有效的。

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.]
于 2013-08-04T16:09:12.030 回答