【问题标题】:Compute dot product of two dictionaries with tuple values in Python在 Python 中计算具有元组值的两个字典的点积
【发布时间】:2020-01-29 07:32:21
【问题描述】:

我有两个看起来像这样的字典:

dict_of_items = tf_idf_by_doc {1: [('dog', 3), ('bird', 0)], 2: [('egret', 2), ('cat', 3), ('bird', 0), ('aardvark', 1)], 3: [('fish', 6), ('bird', 0), ('dog', 1), ('aardvark', 5)], 4: [('fish', 6), ('bird', 0), ('dog', 1), ('aardvark', 2)], 5: [('egret', 4), ('bird', 0)], 6: [('bird', 0)], 7: [('dog', 5), ('bird', 0)], 8: [('bird', 0), ('aardvark', 1)]}

dict_of_search = {1: [('bird', 0), ('dog', 1), ('cat', 3)]}

我需要计算dict_of_searchdict_of_items 中的每个键 之间的点积,然后存储得到的点积值并按键跟踪。我的意思是……

dict_of_items 中,1 和dict_of_search 中的项目有一个向量:

|      | dict_of_items_1 | dict_of_search |
|:----:|:---------------:|:--------------:|
| bird |        0        |        0       |
|  dog |        3        |        1       |
|  cat |        0        |        3       |

所以我的点积是:3

与 dict_of_search 相比,所需的结果将是 dict_of_items 中的键及其各自的点积的字典(这将永远是一个项目),按点积按降序排序。

但是,我不确定如何将我的字典的形状转换为两个数组来执行向量计算,尤其是当其中一个术语不出现时处理(例如,在上面的示例中 cat 确实不会出现在 dict_of_items_1 中的键 1 中。

我已经尝试过使用numpy...

import numpy as numpy

def main():
    test_arr_1 = [1,2,3]
    test_arr_2 = [3,2,6]

    first_dot_product = numpy.dot(test_arr_1, test_arr_2)

    print("First Example: ", first_dot_product)

    test_arr_3 = [3,0,1]
    test_arr_4 = [2,10]

    second_dot_product = numpy.dot(test_arr_3, test_arr_4)

    print("Second Example Missing Value: ", second_dot_product)

main()

但这失败了,因为向量的大小和形状不同。

ValueError: shapes (3,) and (2,) not aligned: 3 (dim 0) != 2 (dim 0)

我也尝试过将字典值重塑为列表:

def main():
    dict_of_items = {'1': [('bird', 0), ('dog', 3), ('egret', 2), ('bird', 0), ('aardvark', 1), ('cat', 3), ('dog', 1), ('bird', 0), ('fish', 6), ('aardvark', 5), ('dog', 1), ('bird', 0), ('fish', 6), ('aardvark', 2), ('egret', 4), ('bird', 0), ('bird', 0), ('bird', 0), ('dog', 5), ('bird', 0), ('aardvark', 1)]}

    test_list_of_lists = []
    for k, v in dict_of_items.items():
        curr_list = []
        for aTuple in v:
            curr_list.append(aTuple[1])
        test_list_of_lists.append(curr_list)

    print(test_list_of_lists)   

main()

但这只是错误地将所有内容合并到一个列表中:[[0, 3, 2, 0, 1, 3, 1, 0, 6, 5, 1, 0, 6, 2, 4, 0, 0, 0, 5, 0, 1]]

我还查看了this post,但该字典的格式要简单得多。

【问题讨论】:

  • 为什么要投反对票?我发布了最少的代码、问题、期望的结果以及我尝试过的内容?
  • 我投了反对票,因为完全不清楚您要执行什么操作。您称其为“点积”,但它不是点积。目前尚不清楚您的示例输出如何对应于您的示例输入;例如,dict_of_items 中的 ('cat', 3) 以及大部分 birddog 值似乎都被完全忽略了。
  • 两个矩阵相乘不是乘积吗?如果不是,请让我知道我是否应该改写为“矩阵数学”。 ('cat', 3)dict_of_items 中出现多次,用于多个键,并且不会被完全忽略...但是,在键1 中,没有出现('cat', 3),因此它被忽略了。我不明白你最后的评论。只有 _first_ 的矩阵数学/点积示例已完成,其中执行了搜索向量和第一项 (key = 1)。 @user2357112
  • 编辑 - 我为 dict_of_items 发布了不正确的字典。我很抱歉。请参阅编辑@user2357112
  • 有了更正的字典,问题就更有意义了。

标签: python python-3.x dictionary tuples


【解决方案1】:

要计算 dict_of_searchdict_of_items 上的值的 doc 积,您可以这样做:

def prod(source, target):
    return sum(source.get(key, 0) * target.get(key, 0) for key in source.keys() | target.keys())


dict_of_items = {1: [('dog', 3), ('bird', 0)], 2: [('egret', 2), ('cat', 3), ('bird', 0), ('aardvark', 1)],
                 3: [('fish', 6), ('bird', 0), ('dog', 1), ('aardvark', 5)],
                 4: [('fish', 6), ('bird', 0), ('dog', 1), ('aardvark', 2)], 5: [('egret', 4), ('bird', 0)],
                 6: [('bird', 0)], 7: [('dog', 5), ('bird', 0)], 8: [('bird', 0), ('aardvark', 1)]}

dict_of_search = {1: [('bird', 0), ('dog', 1), ('cat', 3)]}

for k, v in dict_of_items.items():
    for se in dict_of_search.values():
        print(k, prod(dict(v), dict(se)))

输出

1 3
2 9
3 1
4 1
5 0
6 0
7 5
8 0

如果要将结果存储在字典中,请执行以下操作:

result = {}
for k, v in dict_of_items.items():
    for se in dict_of_search.values():
        result[k] = prod(dict(v), dict(se))

print(result)

输出

{1: 3, 2: 9, 3: 1, 4: 1, 5: 0, 6: 0, 7: 5, 8: 0}

【讨论】:

  • 这些值看起来正确。我如何在字典中捕获它,而不是仅打印值?
【解决方案2】:

如果您将元组转换为字典,如下所示会更容易。那么我们可以像这样使用列表推导

dict_of_items = {key:dict(value) for key, value in dict_of_items.items()}
dict_of_search = {key:dict(value) for key, value in dict_of_search.items()}

{item_key: sum([search[key]*item.get(key,0)  for key in search.keys()]) 
     for item_key, item in dict_of_items.items() 
     for search in dict_of_search.values()}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-30
    • 2014-01-05
    • 2016-05-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多