从numpy

时间:2015-05-05 16:11:33

标签: python arrays numpy matrix vectorization

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

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)
我错过了什么?

如果这是一个微不足道的问题,我会提前道歉,但如果没有循环,我无法弄清楚如何做到这一点。

3 个答案:

答案 0 :(得分:3)

你可以这样做:

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]

答案 1 :(得分: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

更大的x1输入数组和2001000元素,这是运行时结果 -

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

答案 2 :(得分:0)

我不确定这是否是你想要的阵型规则,但你可以用列表理解来做到这一点:

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]