【发布时间】:2015-02-11 16:51:12
【问题描述】:
我有一个(大)长度为 N 的 k 个不同函数数组,以及一个长度为 N 的 abcissa 数组。我想评估 abcissa 处的函数以返回一个长度为 N 的纵坐标数组,而且至关重要的是,我需要非常快地完成它。
我在调用 np.where 时尝试了以下循环,这太慢了:
创建一些假数据来说明问题:
def trivial_functional(i): return lambda x : i*x
k = 250
func_table = [trivial_functional(j) for j in range(k)]
func_table = np.array(func_table) # possibly unnecessary
我们有一个包含 250 个不同功能的表格。现在,我创建了一个大型数组,其中包含这些函数的许多重复条目,以及一组相同长度的点,这些点应在这些点处进行评估。
Npts = 1e6
abcissa_array = np.random.random(Npts)
function_indices = np.random.random_integers(0,len(func_table)-1,Npts)
func_array = func_table[function_indices]
最后,循环遍历数据使用的每个函数,并在相关点集上对其进行评估:
desired_output = np.zeros(Npts)
for func_index in set(function_indices):
idx = np.where(function_indices==func_index)[0]
desired_output[idx] = func_table[func_index](abcissa_array[idx])
这个循环在我的笔记本电脑上大约需要 0.35 秒,这是我代码中最大的瓶颈一个数量级。
有人知道如何避免对 np.where 的盲目查找调用吗?有没有巧妙地使用 numba 可以加快这个循环?
【问题讨论】:
-
可能想将此发布到 codereview.stackexchange.com
-
如果您跳过对
np.where的调用并使用布尔索引(即idx = function_indices == func_index),您会更快,其他一切都保持不变。 -
@Jaime - 此更改实际上将运行时间减慢到 0.5 秒
-
“where”行和最后一个函数评估行之间的时间间隔是多少?
-
所以是对
where的反复调用会害死你。您需要某种排序或 groupby 来组织索引一次,然后在循环中提供快速访问。
标签: python performance numpy scientific-computing numba