将1d数组转换为下三角矩阵

Pan*_*al. 11 python numpy python-3.x

我想将1维数组转换为较低的零对角矩阵,同时保留所有数字.

我知道numpy.tril函数,但它用零替换了一些元素.我需要扩展矩阵以包含所有原始数字.

例如:

[10,20,40,46,33,14,12,46,52,30,59,18,11,22,30,2,11,58,22,72,12]

应该

0
10 0
20 40 0
46 33 14 0
12 46 52 30 0
59 18 11 22 30 0
2 11 58 22 72 12 0
Run Code Online (Sandbox Code Playgroud)

Div*_*kar 10

输入数组保存所需的所有值以填充较低的对角线位置,这里有一种方法masking-

def fill_lower_diag(a):
    n = int(np.sqrt(len(a)*2))+1
    mask = np.tri(n,dtype=bool, k=-1) # or np.arange(n)[:,None] > np.arange(n)
    out = np.zeros((n,n),dtype=int)
    out[mask] = a
    return out
Run Code Online (Sandbox Code Playgroud)

样品运行 -

In [82]: a
Out[82]: 
array([10, 20, 40, 46, 33, 14, 12, 46, 52, 30, 59, 18, 11, 22, 30,  2, 11,
       58, 22, 72, 12])

In [83]: fill_lower_diag(a)
Out[83]: 
array([[ 0,  0,  0,  0,  0,  0,  0],
       [10,  0,  0,  0,  0,  0,  0],
       [20, 40,  0,  0,  0,  0,  0],
       [46, 33, 14,  0,  0,  0,  0],
       [12, 46, 52, 30,  0,  0,  0],
       [59, 18, 11, 22, 30,  0,  0],
       [ 2, 11, 58, 22, 72, 12,  0]])
Run Code Online (Sandbox Code Playgroud)

带有5k x 5k形状的大阵列上的计时-

In [146]: np.random.seed(0)

In [147]: n = 5000

In [148]: a = np.random.randint(0,9,n*(n+1)/2)

In [149]: %timeit tril_indices_app(a) #@Brenlla's solution
1 loop, best of 3: 218 ms per loop

In [151]: %timeit fill_lower_diag(a) # From this post
10 loops, best of 3: 43.1 ms per loop
Run Code Online (Sandbox Code Playgroud)

  • 是的,掩码索引可以更快更快,内存效率更高(前提是你索引[足够的元素](/sf/answers/3223077511/)).我的方法只对相对于三角矩阵大小的小"k"有竞争力 (2认同)

Bre*_*lla 5

你也可以使用numpy函数np.tril_indices:

arr = np.array([10,20,40,46,33,14,12,46,52,30,59,18,11,22,30,2,11,58,22,72,12])
n = int(np.sqrt(len(arr)*2))+1
Run Code Online (Sandbox Code Playgroud)

生成零矩阵并使用您的值填充下半部分:

idx = np.tril_indices(n, k=-1, m=n)
matrix = np.zeros((n,n)).astype(int)
matrix[idx] = arr
array([[ 0,  0,  0,  0,  0,  0,  0],
       [10,  0,  0,  0,  0,  0,  0],
       [20, 40,  0,  0,  0,  0,  0],
       [46, 33, 14,  0,  0,  0,  0],
       [12, 46, 52, 30,  0,  0,  0],
       [59, 18, 11, 22, 30,  0,  0],
       [ 2, 11, 58, 22, 72, 12,  0]])
Run Code Online (Sandbox Code Playgroud)