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)
你也可以使用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)