优化Dict值(列表)乘法

时间:2018-11-04 00:41:05

标签: python dictionary optimization iteration matrix-multiplication

我有两个字典元素,如下所示:初始(25个键值对)结果(100个键值对)

Initial: {0: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0],....... 24: [0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0]}

Results: {'0': [360, 0, 0, 0, 0, 1, 0, 0, 3, 3, 0, 0, 15, 0, 14, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 2, 0, 0, 0, 0, 1, 0, 3, 3, 1, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 2, 0, 1, 0, 0, 3, 1, 0, 1, 0, 0, 0, 1, 2, 0, 2, 0, 0, 0, 137, 21, 78, 65, 241, 31, 30, 88, 152, 3, 13, 67, 31, 145, 132, 37, 1, 107, 120, 171, 39, 35, 31, 8, 24, 0, 0, 0, 0, 0],......'100': [183, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 4, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 2, 8, 1, 3, 1, 0, 3, 3, 0, 1, 1, 3, 2, 1, 1, 4, 0, 2, 1, 3, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 76, 10, 25, 33, 121, 14, 6, 40, 62, 2, 5, 34, 23, 66, 61, 28, 1, 56, 46, 69, 23, 10, 14, 1, 13, 1, 0, 0, 0, 0]}

在每次迭代中,我将“结果”字典的每个值乘以“初始”字典中的一个值,并调用传递该乘积的函数,该乘积将获取另一个值,并在整个“初始”字典值中进行迭代。我正在使用以下代码进行此操作:

for z in Initial.keys():
        for i in sorted(Results.keys()):
            result = {i :[x*y for x, y in zip(Initial[z], Results[i])]}  

一个完整的周期大约需要1分钟,我将需要执行至少5000个周期才能观察到最终结果。任何有关提高性能/代码优化的建议将不胜感激。

1 个答案:

答案 0 :(得分:1)

您的值是列表,因此您必须一次乘以一个元素。您可以先将值(列表)转换为数组,然后使用向量化乘法,从而消除了对列表理解和元素智能乘法的使用,如下所示:

# Converting the values to arrays once for all
Initial = {k:np.array(v) for k,v in Initial.items()}
Results = {k:np.array(v) for k,v in Results.items()}

# Now just using vectorized multipliction
for z in Initial.keys():
    for i in sorted(Results.keys()):
        result = {i :Initial[z] * Results[i]}  

由于您没有提供完整的数据,因此我尝试了约一百万次迭代的代码,并发现矢量化的代码要快得多。在原始数据上尝试一下,看看是否可以加快速度(应该这样做)。


用于比较时间的测试用例

您的列表理解版本耗时1分6秒

for ii in range(500000):
    for z in Initial.keys():
        for i in sorted(Results.keys()):
            result = {i :[x*y for x, y in zip(Initial[z], Results[i])]}  

以下矢量化操作耗时2.9秒

for ii in range(500000):
    for z in Initial.keys():
        for i in sorted(Results.keys()):
            result = {i :Initial[z] * Results[i]}