从numpy中对角线下的元素数组创建一个矩阵

create a matrix from array of elements under diagonal in numpy

我想使用一个列表创建一个矩阵,该列表的元素是矩阵对角线下方的元素。

import numpy as np
x1 = np.array([0.9375, 0.75, 0.4375, 0.0, 0.9375, 0.75, 0.4375, 0.9375, 0.75, 0.9375])
x1

我想要的矩阵是

array([[ 1.    ,  0.9375,  0.75  ,  0.4375,  0.    ],
   [ 0.9375,  1.    ,  0.9375,  0.75  ,  0.4375],
   [ 0.75  ,  0.9375,  1.    ,  0.9375,  0.75  ],
   [ 0.4375,  0.75  ,  0.9375,  1.    ,  0.9375],
   [ 0.    ,  0.4375,  0.75  ,  0.9375,  1.    ]])

我认为您可以使用 np.tril 来做到这一点,但结果出乎我的意料。

mat = np.tril(x1, k = -1  )
print(mat)

我错过了什么?

如果这是一个微不足道的问题,但我无法在不循环的情况下弄清楚如何解决。

我不确定这是否是您想要的形成规则,但您可以通过列表理解来实现:

x1 = np.array([0.9375, 0.75, 0.4375, 0.0, 0.9375, 0.75, 0.4375, 0.9375, 0.75, 0.9375])
x2 = [ [ x1[i-1-j] if j<i else x1[-i-1+j] for j in range(5) ] for i in range(5) ]
x2 = [ [ 1 if i==j else x2[i][j] for j in range(5) ] for i in range(5) ]
for el in x2:
    print el

给我

[1, 0.9375, 0.75, 0.4375, 0.0]
[0.9375, 1, 0.9375, 0.75, 0.4375]
[0.75, 0.9375, 1, 0.9375, 0.75]
[0.4375, 0.75, 0.9375, 1, 0.9375]
[0.0, 0.4375, 0.75, 0.9375, 1]

可以使用boolean indexing/mask-

N = 5            # Output array length
out = np.eye(N)  # Initialize output array with ones on diagonal

# Mask of upper triangular region except the diagonal region
range1 = np.arange(N)
mask = range1[:,None] < np.arange(N) 
# Or simply: mask = np.triu(np.ones((N,N)),1)==1

# Insert x1's at upper diagonal region (except the diagonal) and paste 
# transposed version of itself on lower diagonal region (including diagonal)
out[mask] = x1
out[~mask] = out.T[~mask]

基准测试

对于迄今为止发布的处理 numpy 数组的解决方案,这里是给定输入的快速运行时测试 -

In [110]: %timeit triu_indices_based(x1,N)
10000 loops, best of 3: 19.9 µs per loop

In [111]: %timeit mask_based(x1,N)
100000 loops, best of 3: 6.88 µs per loop

具有 x12001000 元素的较大输入数组,这是运行时结果 -

In [91]: %timeit mask_based(x1,N)
10 loops, best of 3: 34.9 ms per loop

In [92]: %timeit triu_indices_based(x1,N)
10 loops, best of 3: 80.9 ms per loop

你可以这样做:

x = np.ones((5, 5), dtype=float)
x[np.triu_indices(5, 1)] = x1        # sets the upper triangle
x[np.triu_indices(5, 1)[::-1]] = x1  # sets the lower triangle 

在最后一行中,索引是相反的,因为您的 x1 是为上三角订购的。如果感觉更直观,您也可以使用 x[np.tril_indices(5, -1)] = x1[::-1]