我的字典:
d = {'a':1, 'b':2, 'c':3}
和我的钥匙清单:
keys = np.array(['a','b','a','c','a','b'])
我希望在不使用for循环的情况下拥有相应值的列表
我尝试通过以下方式使用for循环,但出于我的工作目的,这在计算上过于昂贵。
这是for循环版本。
l = [d[i] for i in keys]
您是否知道一个没有循环的版本,也许利用了np.array的广播..masks?
答案 0 :(得分:3)
# Approach 1
对于大型阵列,可以使用np.vectorize
作为更好的扩展解决方案:
d = {'a':1, 'b':2, 'c':3}
keys = np.array(['a','b','a','c','a','b'])
np.vectorize(d.get)(keys)
# array([1, 2, 1, 3, 1, 2])
# Approach 2
另一种方法是定义一个结构化数组,该数组允许使用混合类型,并使用np.searchsorted
:
a = np.array(list(d.items()), dtype=[('letter', 'U1'), ('digit', 'i4')])
a['digit'][np.searchsorted(a['letter'], keys)]
# array([1, 2, 1, 3, 1, 2])
让我们检查时间:
d = {'a':1, 'b':2, 'c':3}
keys = np.concatenate([np.array(['a','b','a','c','a','b'])]*1000)
def str_array(d, keys):
items = list(d.items())
# more general solution checking appropiate dtype
dtype_int = np.max(list(zip(*items))[1]).itemsize
# setting corresponding dtype using f-strings
a = np.array(items, dtype=[('letter', 'U1'), ('digit', f'i{dtype_int}')])
return a['digit'][np.searchsorted(a['letter'], keys)]
%timeit [d[i] for i in keys]
# 1.86 ms ± 99.7 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit np.vectorize(d.get)(keys)
# 808 µs ± 18.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit str_array(d, keys)
# 75.7 µs ± 5.1 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
如您所见,与简单的列表理解相比,使用np.searchsorted
的第二种方法可以提高 20x
的速度。
答案 1 :(得分:0)
我不了解相对性能,但是我发现此解决方案非常快速且简单。 将您的密钥转换为系列,然后使用内置的map函数返回您的答案。
import pandas as pd
d = {'a':1, 'b':2, 'c':3}
keys = np.array(['a','b','a','c','a','b'])
keys1 = pd.Series(keys)
keys1.map(d)