使用numpy列表到矩阵转换

But*_*ood 2 python numpy type-conversion

从浮动列表开始,即

register = [11, 12, 13, 23, 24, 34]
Run Code Online (Sandbox Code Playgroud)

我想生成对称矩阵,其中对角线的元素等于零,即

[[  0.  11.  12.  13.]
 [ 11.   0.  23.  24.]
 [ 12.  23.   0.  34.]
 [ 13.  24.  34.   0.]]
Run Code Online (Sandbox Code Playgroud)

所以我选择创建一个尺寸为4 x 4的零,然后用我的列表中的元素填充.在设置进度指示器并考虑偏移以不覆盖对角线的零之后,然后我将向东(或向南)移动,直到消耗了达到矩阵极限的先前确定的步数.在递增进度并重置初始步数计数器后,我可以进入下一列(行)以继续进行.但是,我错误地使用了我现在的代码(至少一次 - 这是我与numpy的第一次接触)并且只收获了

[[  0.  11.  12.  13.]
 [ 11.   0.  23.   0.]
 [ 12.  23.   0.   0.]
 [ 13.   0.   0.   0.]]
Run Code Online (Sandbox Code Playgroud)

我的代码:

 import numpy as np
 dimension = 4    # other matrices' dimensions will be larger
 matrix = np.zeros((dimension,dimension))

 register = [11, 12, 13, 23, 24, 34]

 progress = 0
 inner_step = 0
 i = 0

 for progress in range(0, (dimension + 1)):
 permitted_steps = dimension - progress
 for i in range(progress, permitted_steps-1):
     matrix[(progress, inner_step+1+offset)] = register[0]
     matrix[(inner_step+1+offset, progress)] = register[0]
     inner_step += 1
     del register[0]

 progress += 1
 inner_step = 0
 offset += 1
Run Code Online (Sandbox Code Playgroud)

使用的目标环境是适用于Windows的Python 2.7(Continuum Anaconda).

Div*_*kar 5

这是一种矢量化方法,利用broadcastingmasking/boolean-indexing-

r = np.arange(dimension)
mask = r[:,None] < r # Or in one step : ~np.tri(dimension,dtype=bool)
matrix[mask] = register
matrix.T[mask] = register
Run Code Online (Sandbox Code Playgroud)

如果您需要dimension根据给定进行计算register,我们可以使用:

dimension = int(np.ceil(np.sqrt(2*len(register))))
Run Code Online (Sandbox Code Playgroud)

并且断言dimension,我们可以:

assert dimension*(dimension-1)//2 == len(register)
Run Code Online (Sandbox Code Playgroud)

另外,对于性能,请考虑使用数组版本register.

样品运行 -

In [43]: import numpy as np
    ...: dimension = 4    # other matrices' dimensions will be larger
    ...: matrix = np.zeros((dimension,dimension))
    ...: 
    ...: register = [11, 12, 13, 23, 24, 34]

In [44]: r = np.arange(dimension)
    ...: mask = r[:,None] < r
    ...: matrix[mask] = register
    ...: matrix.T[mask] = register

In [45]: matrix
Out[45]: 
array([[ 0., 11., 12., 13.],
       [11.,  0., 23., 24.],
       [12., 23.,  0., 34.],
       [13., 24., 34.,  0.]])
Run Code Online (Sandbox Code Playgroud)

怎么masking可能比生成所有三角形指数更好

生成索引会占用比创建布尔数组更多的内存,因为布尔数组本质上具有内存效率,因此转换为更好的性能,尤其是在大型数组上.关于此的时间会试图证明 -

In [3]: import numpy as np
   ...: dimension = 5000    # other matrices' dimensions will be larger
   ...: register = np.random.randint(0,10,dimension*(dimension-1)//2)

# With masking and boolean-indexing
In [4]: %%timeit
   ...: matrix = np.zeros((dimension,dimension),dtype=int)
   ...: r = np.arange(dimension)
   ...: mask = r[:,None] < r
   ...: matrix[mask] = register
   ...: matrix.T[mask] = register
10 loops, best of 3: 108 ms per loop

# With triangular indices indexing
In [5]: %%timeit
   ...: N = dimension
   ...: matrix = np.zeros((dimension,dimension),dtype=int)
   ...: idx = np.triu_indices(N, k=1)
   ...: matrix = np.zeros((N, N))
   ...: matrix[idx] = register
   ...: matrix.T[idx] = register
1 loop, best of 3: 364 ms per loop
Run Code Online (Sandbox Code Playgroud)


use*_*ica 5

只需致电scipy.spatial.distance.squareform:

>>> import scipy.spatial.distance
>>> scipy.spatial.distance.squareform([11, 12, 13, 23, 24, 34])
array([[ 0, 11, 12, 13],
       [11,  0, 23, 24],
       [12, 23,  0, 34],
       [13, 24, 34,  0]])
Run Code Online (Sandbox Code Playgroud)

您想要的转换与从压缩距离矩阵到方形距离矩阵的转换相同,并scipy.spatial.distance.squareform执行该转换(及其反转).但是要注意dtypes; [11, 12, 13, 23, 24, 34]是一个int的列表,而不是浮点数,并传递给squareform它将给你一个int数组.result.astype(float)如果需要浮点数,可以将输入转换为浮点数或调用.