【问题标题】:Getting values from dictionary of distances to build a distance matrix从距离字典中获取值以构建距离矩阵
【发布时间】:2019-05-03 19:51:46
【问题描述】:

我有一本包含以下格式的距离信息的字典

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

【问题讨论】:

    标签: python numpy dictionary


    【解决方案1】:

    我假设您可以保证以一种或另一种方式定义距离。所以我建议使用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】:

      你可以这样做:

      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】:

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

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

        【讨论】:

        • @Cohan 所以第一个元素 [0, 0] 是 0(因为 i==j 被跳过),第二个元素 [0, 1] 是读取距离[ordered_list[i]][ordered_list [j]],根据有序列表翻译距离["a"]["b"]。
        • 是的,我意识到你在做什么。只是很难阅读。迭代可迭代对象而不是索引
        【解决方案4】:

        你可以试试这个,让我知道它是否适合你的要求。

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-09-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-06-11
          • 2016-12-06
          • 2011-08-08
          • 1970-01-01
          相关资源
          最近更新 更多