到 (row,col,distance) 列表的距离的 Numpy 数组

Mik*_*son 0 python numpy scipy python-3.x pdist

我有一个 nd 数组,如下所示:

[[ 0.          1.73205081  6.40312424  7.21110255  2.44948974]
 [ 1.73205081  0.          5.09901951  5.91607978  1.        ]
 [ 6.40312424  5.09901951  0.          1.          4.35889894]
 [ 7.21110255  5.91607978  1.          0.          5.09901951]
 [ 2.44948974  1.          4.35889894  5.09901951  0.        ]]
Run Code Online (Sandbox Code Playgroud)

该数组中的每个元素都是一个距离,我需要将其转换为包含行、列、距离的列表,如下所示:

l = [(0,0,0),(0,1, 1.73205081),(0,2, 6.40312424),...,(1,0, 1.73205081),(1,1,0),...,(4,4,0)] 
Run Code Online (Sandbox Code Playgroud)

此外,删除对角线元素会很酷,而且元素 (j,i) 因为 (i,j) 已经存在。本质上,是否可以只取它的顶部三角矩阵?

这是否可以有效地完成(没有很多循环)?我用 squareform 创建了这个数组,但找不到任何文档来执行此操作。

hpa*_*ulj 5

squareform做这一切。阅读文档并进行实验。它在两个方向上都起作用。如果给它一个矩阵,它会返回上三角形值(压缩形式)。如果你给它这些值,它就会返回矩阵。

In [668]: M
Out[668]: 
array([[ 0. ,  0.1,  0.5,  0.2],
       [ 0.1,  0. ,  2. ,  0.3],
       [ 0.5,  2. ,  0. ,  0.2],
       [ 0.2,  0.3,  0.2,  0. ]])
In [669]: spatial.distance.squareform(M)
Out[669]: array([ 0.1,  0.5,  0.2,  2. ,  0.3,  0.2])
In [670]: v=spatial.distance.squareform(M)
In [671]: v
Out[671]: array([ 0.1,  0.5,  0.2,  2. ,  0.3,  0.2])
In [672]: spatial.distance.squareform(v)
Out[672]: 
array([[ 0. ,  0.1,  0.5,  0.2],
       [ 0.1,  0. ,  2. ,  0.3],
       [ 0.5,  2. ,  0. ,  0.2],
       [ 0.2,  0.3,  0.2,  0. ]])
Run Code Online (Sandbox Code Playgroud)

您还可以指定forcechecks参数,但如果没有这些参数,它就只是形状。

索引可以来自triu

In [677]: np.triu_indices(4,1)
Out[677]: 
(array([0, 0, 0, 1, 1, 2], dtype=int32),
 array([1, 2, 3, 2, 3, 3], dtype=int32))

In [680]: np.vstack((np.triu_indices(4,1),v)).T
Out[680]: 
array([[ 0. ,  1. ,  0.1],
       [ 0. ,  2. ,  0.5],
       [ 0. ,  3. ,  0.2],
       [ 1. ,  2. ,  2. ],
       [ 1. ,  3. ,  0.3],
       [ 2. ,  3. ,  0.2]])
Run Code Online (Sandbox Code Playgroud)

只是为了检查一下,我们可以用这些值填充 4x4 矩阵

In [686]: A=np.vstack((np.triu_indices(4,1),v)).T
In [687]: MM = np.zeros((4,4))
In [688]: MM[A[:,0].astype(int),A[:,1].astype(int)]=A[:,2]
In [689]: MM
Out[689]: 
array([[ 0. ,  0.1,  0.5,  0.2],
       [ 0. ,  0. ,  2. ,  0.3],
       [ 0. ,  0. ,  0. ,  0.2],
       [ 0. ,  0. ,  0. ,  0. ]])
Run Code Online (Sandbox Code Playgroud)

这些triu索引还可以从以下位置获取值M

In [693]: I,J = np.triu_indices(4,1)
In [694]: M[I,J]
Out[694]: array([ 0.1,  0.5,  0.2,  2. ,  0.3,  0.2])
Run Code Online (Sandbox Code Playgroud)

squareform使用编译代码,spatial.distance._distance_wrap所以我预计对于大型数组来说它会相当快。唯一的问题是它只返回压缩形式的值,而不是索引。但给定形状,总可以计算出指数。它们不需要与值一起存储。