我有一组非常大的(200k +)键/值对,我需要检索非常大(有时是全部)的值。显而易见的方法是使用字典
values = {lookup.get(key) for key in key_set}
这在我的代码中变得非常耗时,我想知道是否有更快的方法来实现NumPy数组。我一直在尝试使用包含两列和n行的数组,以便对任何单独的键使用:
value = lookup_array[lookup_array[:,0] == key, 1]
但我不知道如何在没有昂贵的迭代的情况下将其扩展到许多密钥。我看过了:
values = lookup_array[np.in1d(lookup_array[:,0], key_set), 1]
但这似乎也很耗时。
有没有其他方法可以快速大量查找非连续值而无需迭代?
答案 0 :(得分:3)
如果某些特殊条件适用,您可以使用NumPy索引作为字典查找的快速替代方法。
键必须是整数
你有足够的内存来创建一个NumPy数组,其大小与 您希望查找的最大键值(以便所有键对应于数组中的有效索引。)
想法是使用
lookup_array = np.empty((M,), dtype=values.dtype)
lookup_array[keys] = values
result = lookup_array[key_set]
而不是
result = {lookup_dict.get(key) for key in key_set}
例如,
import numpy as np
import pandas as pd
def using_dict(lookup_dict, key_set):
return {lookup_dict.get(key) for key in key_set}
def using_array(lookup_array, key_set):
return lookup_array[key_set]
def using_pandas(df, key_set):
return df.loc[df['a'].isin(key_set)]
M = 10**6
N = 2*10**5
K = 10**4
keys = np.random.randint(M, size=(N,))
values = np.random.random((N,))
lookup_dict = dict(zip(keys, values))
lookup_array = np.empty((M,), dtype=values.dtype)
lookup_array[keys] = values
df = pd.DataFrame(np.column_stack([keys, values]), columns=list('ab'))
key_set = np.random.choice(keys, size=(K,))
这是上述方法的时间基准(使用IPython):
In [25]: %timeit using_array(lookup_array, key_set)
10000 loops, best of 3: 22.4 µs per loop
In [26]: %timeit using_dict(lookup_dict, key_set)
100 loops, best of 3: 3.73 ms per loop
In [24]: %timeit using_pandas(df, key_set)
10 loops, best of 3: 38.9 ms per loop
答案 1 :(得分:3)
这是np.searchsorted
-
lookup_array
这假定np.searchsorted
的键在第一列中排序。如果不是这种情况,您可以将可选的分拣机参数与return render(request,"home.html")
一起使用。
答案 2 :(得分:0)
加载字典这个庞大的内存有点不好,然后增加了查找的开销。如果这是一个数据结构,那么您经常使用数据库引擎。如果你不喜欢SQL,有KEY / VALUE数据库。它们针对查找进行了高度优化。