Numpy列表的距离(行,列,距离)

时间:2017-01-30 05:26:59

标签: python python-3.x numpy scipy 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.        ]]

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

l = [(0,0,0),(0,1, 1.73205081),(0,2, 6.40312424),...,(1,0, 1.73205081),(1,1,0),...,(4,4,0)] 

此外,删除对角线元素以及元素(j,i),因为(i,j)已经存在,这将是很酷的。基本上,是否可以只采用这个顶部三角矩阵?

这是否可以有效地完成(没有很多循环)?我用方形创建了这个数组,但是找不到任何文档可以做到这一点。

4 个答案:

答案 0 :(得分:4)

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. ]])

您还可以指定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]])

为了检查,我们可以使用这些值填充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. ]])

这些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])

squareform使用spatial.distance._distance_wrap中的编译代码,所以我希望它对于大型数组来说会非常快。唯一的问题是它只返回压缩的表单值,而不是索引。但考虑到形状,可以始终计算指数。他们不需要与值一起存储。

答案 1 :(得分:2)

如果您的输入为x,请先生成索引:

i0,i1 = np.indices(x.shape)

然后:

np.concatenate((i1,i0,x)).reshape(3,5,5).T

这为您提供了整个矩阵的第一个结果。

至于只拍摄上三角形,您可能会考虑尝试np.triu(),但我不确定您正在寻找的确切结果。你可以弄清楚如何掩盖你现在不想要的部分。

答案 2 :(得分:0)

你可以试试这个,

print([(x,y, value) for (x,y), value in np.ndenumerate(numpymatrixarray)])

output [(0, 0, 0.0), (0, 1, 1.7320508100000001), (0, 2, 6.4031242400000004), (0, 3, 7.2111025499999997), (0, 4, 2.4494897400000002), (1, 0, 1.7320508100000001), (1, 1, 0.0), (1, 2, 5.0990195099999998), (1, 3, 5.9160797799999996), (1, 4, 1.0), (2, 0, 6.4031242400000004), (2, 1, 5.0990195099999998), (2, 2, 0.0), (2, 3, 1.0), (2, 4, 4.3588989400000004), (3, 0, 7.2111025499999997), (3, 1, 5.9160797799999996), (3, 2, 1.0), (3, 3, 0.0), (3, 4, 5.0990195099999998), (4, 0, 2.4494897400000002), (4, 1, 1.0), (4, 2, 4.3588989400000004), (4, 3, 5.0990195099999998), (4, 4, 0.0)]

答案 3 :(得分:0)

你真的想要[nxm]矩阵的顶部三角矩阵n>m吗?这将为您提供(nxn-n)/2个元素并丢失m⊖n

中的所有数据

你可能想要的是下三角矩阵:

def tri_reduce(m):
    n=m.shape
    if n[0]>n[1]:
        i=np.tril_indices(n[0],1,n[1])
    else:
        i=np.triu_indices(n[0],1,n[1])
    return np.vstack((i,m[i])).T

将其重建为元组列表需要一个循环但我相信。 list(tri_reduce(m))会给出一个nd数组列表。