从距离字典中获取值以构建距离矩阵

时间:2019-05-03 19:51:47

标签: python numpy dictionary

我有一个字典,其中包含以下格式的距离信息

distances = {"a": {"b": 0.2, "c": 0.4}, "b": {"c": 0.6}}

我想根据列表中的顺序构建距离矩阵:

order = ["a", "b", "c"]

因此所需的输出应如下所示:

[
 0, 0.2, 0.4
 0.2 , 0, 0.6
 0.4, 0.6, 0
]

我尝试了以下方法,但不确定如何前进。感谢您的帮助

dist = np.zeros((len(order), len(order)))
for index1, member1 in enumerate(order):

    curr = distances.get(member1, {})
    for index2, member2 in enumerate(order):
        val = curr.get(member2, None)
        if member2 not in curr:
            val = None
        dist[index1, index2] = val

4 个答案:

答案 0 :(得分:0)

这应该可以,但是假设您的字典的排序方式与列表相同,并且所有对都存在:

l = len(ordered_list)
result = np.zeros((l, l))
for i in range(l):
    for j in range(l):
        if i == j:
            continue
        elif i < j:
            result[i][j] = distances[ordered_list[i]][ordered_list[j]]
        else:
            result[i][j] = distances[ordered_list[j]][ordered_list[i]]

如果此假设不成立,则提供更可靠的解决方案

l = len(ordered_list)
result = np.zeros((l, l))
for i in range(l):
    for j in range(l):
        if i == j:
            continue
        try:
            result[i][j] = distances[ordered_list[i]][ordered_list[j]]
        except KeyError:
            try:
                result[i][j] = distances[ordered_list[j]][ordered_list[i]]
            except:
                raise Exception("pair {0}, {1} does not exist. ". format(ordered_list[i],ordered_list[j]))

答案 1 :(得分:0)

我假设您可以确定以某种方式定义的距离。因此,我建议使用try/except/finally块,您可以在其中翻转查找商品的方式。

import numpy as np

distances = {"a": {"b": 0.2, "c": 0.4}, "b": {"c": 0.6}}
order = ["a", "b", "c"]
dist = np.zeros((len(order), len(order)))

for i, member1 in enumerate(order):
    for j, member2 in enumerate(order):

        if member1 != member2:
            try:
                d = distances[member1][member2]
            except KeyError as e:
                d = distances[member2][member1]
            finally:
                dist[i][j] = d

print(dist)
# [[0.  0.2 0.4]
#  [0.2 0.  0.6]
#  [0.4 0.6 0. ]]

答案 2 :(得分:0)

您可以这样做:

distances = {"a": {"b": 0.2, "c": 0.4}, "b": {"c": 0.6}}
order = ["a", "b", "c"]
dist = np.zeros((len(order), len(order)))

for index1, member1 in enumerate(order):
    curr = distances.get(member1, {})
    for index2, member2 in enumerate(order):
        dist[index1, index2] = curr.get(member2, 0)

print(dist + np.swapaxes(dist, 0, 1))

答案 3 :(得分:0)

您可以尝试一下,让我知道它是否符合您的要求。

distances = {"a": {"b": 0.2, "c": 0.4}, "b": {"c": 0.6}}
order = ["a", "b", "c"]
N = len(order)

#Create N*N array of 0's
dist = [[0]*N for _ in range(N)]


# New dict for array indexing
dd = {'a':0,'b':1,'c':2}

def set_items(x,y,val):
    if x!=y : 
        dist[x][y] = dist[y][x] = val  

#dictionary comprehension of the distances dict. 
[set_items(dd[k],dd[k1],v1) for k,v in distances.items() for k1,v1 in v.items()]

print(dist)

#### Output ####
[
 [0, 0.2, 0.4],
 [0.2, 0, 0.6],
 [0.4, 0.6, 0]
]