优化从大型字典中检索值

时间:2018-01-26 09:17:04

标签: python numpy

我有一个字典id_to_phone。它包含大约350,000个唯一ID(字典键),每个ID代表唯一的电话号码(字典值)。我的要求是获取由我的代码生成的ID的电话号码。从我的代码生成大约10,000到50,000个ID生成&从该ID我需要找到匹配的电话号码&将它存储在一个数组中。我使用了以下代码

count=phone_id.shape[0]
phone_array=np.array([])
for i in range(count):
    phone=id_to_phone[phone_id[i]]
    phone_array=np.append(phone_array,phone)

但是这段代码花了很长时间。有没有办法优化我的代码?

1 个答案:

答案 0 :(得分:4)

您的问题不是字典查找,而是np.append。 NumPy数组是固定大小的连续内存块, 附加到它们之外,超出当前大小,需要重新调整整个内存块并将其移动(复制到其他地方),这需要很长时间,如果你做了一些追加它并不重要但是做很多追加可能会增加数组的大小超出最初分配的数量。 (更正)来自docs

  

返回:arr的副本,其值附加到轴。请注意,append不会就地发生:分配并填充新数组。如果axis为None,则out为展平数组。

所以np.append的每次调用都会复制数组,难怪需要花费很长时间。

使用常规python列表,追加是列表的常量时间。

import timeit

import numpy as np

def np_append():
    arr = np.asarray([])
    for i in range(5000):
        np.append(arr, i)

def list_append():
    ls = []
    for i in range(5000):
        ls.append(i)

if __name__ == "__main__":
    print(timeit.repeat('np_append()', number=10, repeat=3, globals=globals()))
    print(timeit.repeat('list_append()', number=10, repeat=3, globals=globals()))

时间如下

np_append : [0.15639284392818809, 0.15938732610084116, 0.15667122812010348]
list_append : [0.003160736057907343, 0.004024225985631347, 0.003376785898581147]

或者,如果您知道要添加到列表中的元素数量,您可以使用numpy.arrayphone_array = np.zeros((15000, 10))预分配足够的空间,例如,15000个10位数的电话号码