Python numba jitted函数中的动态增长数组

Python numba jitted函数中的动态增长数组,python,numpy,dynamic-arrays,numba,Python,Numpy,Dynamic Arrays,Numba,似乎numba中不支持numpy.resize 在nopython模式下,使用带有numba.jit的动态增长数组的最佳方法是什么 到目前为止,我所能做的最好的事情就是在jitted函数之外定义和调整数组的大小,是否有更好(更整洁)的选项?通常我采用的策略是分配足够多的数组存储来容纳计算,然后跟踪使用的最终索引,然后在返回之前将数组切片到实际大小。这假设您事先知道可以将阵列扩展到的最大大小。我的想法是,在我自己的大多数应用程序中,内存是便宜的,但是在python和jitted函数之间调整大小和切

似乎numba中不支持
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