我有一个长度为N的由k个不同函数组成的数组,以及一个长度为N的abcissa数组。我想在abcissa处评估这些函数,以返回一个长度为N的ordinates数组,并且至关重要的是,我需要非常快地完成这个操作。
我尝试了以下循环调用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来加速此循环?
np.where
的调用并使用布尔索引,即idx = function_indices == func_index
,那么你可以使它更快,其他的一切保持不变。 - Jaimewhere
的重复调用让你崩溃了。你需要一些可以组织索引并在循环中快速访问的排序或分组方式。 - hpaulj