【问题标题】:What is the most efficient way of computing similarity between two dictionnaries of lists?计算两个列表字典之间相似度的最有效方法是什么?
【发布时间】:2020-01-27 11:04:44
【问题描述】:

我想使用集合逻辑计算准确性。我会用一个例子来解释:

对于这两个词典:

d1 = {1: {'hello', 'goodbye'}, 2:{'sayonnara'}, 3:{'origami'}}
d2 = {1: {'goodbye'}, 2:{'hola', 'bye'}, 3:{'bird','origami','giraffe'}}

我想得到这个结果:

{1: 0.5, 2: 0, 3: 0.3333333333333333}

我是这样做的:

from collections import defaultdict
acc=defaultdict(list)
for (k,v1) in d1.items():
    for (k,v) in d2.items():
        nb=len(v1.intersection(v))
        if (nb>0):
            print(nb)
            acc[k] = nb/ (abs(len(v) - len(v1))+1)
            print(acc)
        if k not in acc.keys():
            acc[k] = 0

还有比这更有效的解决方案吗?

【问题讨论】:

  • @DeepSpace 抱歉,我的示例中有一个错误,对于 1,它是 0.5,因为它只有 2 个元素中的 1 个是正确的,而对于 3,它有 3 个元素中的 1 个是正确的。
  • 我们可以假设d1d2 将始终包含相同的键吗?
  • 是的 d1 和 d2 有相同的键。

标签: python python-3.x dictionary set


【解决方案1】:

如果我们在两个 dict 将具有相同键的假设下进行操作,则可以通过具有单个循环的 dict 推导来完成:

print({k1: (len(v1.intersection(d2[k1])) / (abs(len(v1) - len(d2[k1])) + 1))
       for k1, v1 in d1.items()})

输出

{1: 0.5, 2: 0.0, 3: 0.3333333333333333}

这可以通过确保我们只考虑两个字典之间的公共键来概括一下,只是为了安全起见。

print({common_key: (len(d1[common_key].intersection(d2[common_key])) / (abs(len(d1[common_key]) - len(d2[common_key])) + 1))
       for common_key in d1.keys() & d2.keys()})

【讨论】:

  • 这很好,但在这样的情况下会出现问题:d1 = {1: {'hello', 'goodbye'}, 2:{'sayon​​nara'}, 3:{'origami' ,'cat'}} d2 = {1: {'goodbye'}, 2:{'hola', 'bye'}, 3:{'bird','origami'}} 它将为 3 输出 1 而不是 0.5
  • @ATidedHumour 您的代码输出与该示例相同:)
  • 你说得对,我想我知道该怎么做了,谢谢你的帮助,我接受这个答案。
猜你喜欢
  • 2016-09-25
  • 2012-03-11
  • 2018-08-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多