Python numba jitted函数中的动态增长数组
似乎numba中不支持Python numba jitted函数中的动态增长数组,python,numpy,dynamic-arrays,numba,Python,Numpy,Dynamic Arrays,Numba,似乎numba中不支持numpy.resize 在nopython模式下,使用带有numba.jit的动态增长数组的最佳方法是什么 到目前为止,我所能做的最好的事情就是在jitted函数之外定义和调整数组的大小,是否有更好(更整洁)的选项?通常我采用的策略是分配足够多的数组存储来容纳计算,然后跟踪使用的最终索引,然后在返回之前将数组切片到实际大小。这假设您事先知道可以将阵列扩展到的最大大小。我的想法是,在我自己的大多数应用程序中,内存是便宜的,但是在python和jitted函数之间调整大小和切
numpy.resize
在nopython模式下,使用带有numba.jit
的动态增长数组的最佳方法是什么
到目前为止,我所能做的最好的事情就是在jitted函数之外定义和调整数组的大小,是否有更好(更整洁)的选项?通常我采用的策略是分配足够多的数组存储来容纳计算,然后跟踪使用的最终索引,然后在返回之前将数组切片到实际大小。这假设您事先知道可以将阵列扩展到的最大大小。我的想法是,在我自己的大多数应用程序中,内存是便宜的,但是在python和jitted函数之间调整大小和切换非常昂贵
numpy.resize
是一种:
对于1D阵列,这将直接由您自己实现。不幸的是,ND数组要复杂得多,因为nopython numba函数中不支持某些操作:isinstance
、重塑
和元组乘法。以下是1D等效值:
import numpy as np
import numba as nb
@nb.njit
def resize(a, new_size):
new = np.zeros(new_size, a.dtype)
idx = 0
while True:
newidx = idx + a.size
if newidx > new_size:
new[idx:] = a[:new_size-newidx]
break
new[idx:newidx] = a
idx = newidx
return new
如果您不希望出现这种“重复输入”行为,而仅将其用于增加大小,则更容易:
@nb.njit
def resize(a, new_size):
new = np.zeros(new_size, a.dtype)
new[:a.size] = a
return new
这些函数用numba.njit
修饰,因此可以在nopython模式下的任何numba函数中调用
不过需要注意的是:通常情况下,你不想调整大小——或者如果你想调整大小,那么请确保你选择了一种有吸引力的方法。如果您可以估计最大长度,那么最好立即预先分配一个大小正确(或稍微过度分配)的数组。谢谢,每次数组满了,我都会将数组的大小调整2倍,因此我会在python和jitted函数之间切换log(max_size)。你认为这种转换量是真正的瓶颈吗?一个真正的问题是每次复制数组的1.5个因素,我很乐意将其去掉,但我想这是不知道最大大小的代价(我可能只是使用一个可笑的初始大小,只要它适合RAM)。如果不实际分析代码,很难判断瓶颈是什么(cProfile和line_profiler与timeit一样非常有用)。这取决于您的具体应用程序。谢谢,这正是我想要的。很遗憾,对于ND阵列没有简单的解决方案。您可以使用np.empty(new_size,a.dtype)来获得非常小且有争议的性能增益。
@nb.njit
def resize(a, new_size):
new = np.zeros(new_size, a.dtype)
new[:a.size] = a
return new