我想用生成的值填充一个 numpy 数组。这些值由生成器函数生成。数组长度不太长,通常 <100,但是这个数组生成了很多次,所以我想知道是否可以通过一些花哨的 numpy 用法来优化它。
到目前为止,我已经可以用 vanilla python 做到这一点:
def generate():
return generated_data
array = np.asarray([generate() for _ in range(array_length)])
我也尝试过使用 np.full(shape, fill_value)
:
np.full((array_length, generated_data_size), generate())
但这是只调用一次 generate()
函数,而不是对数组中的每个索引调用一次。
我也尝试过 np.vectorize()
,但我无法让它生成适当形状的数组。
最佳答案
NumPy 无法做任何事情来加速重复调用并非设计用于与 NumPy 交互的函数的过程。
优化它的“numpy 的花哨用法”方法是手动重写您的 generate
函数以使用 NumPy 操作生成整个输出数组,而不是仅支持单个值。这就是 NumPy 的工作方式,也是 NumPy 必须 的工作方式;任何涉及为每个数组单元一遍又一遍地调用 Python 函数的解决方案都将受到 Python 开销的限制。 NumPy 只能加速 NumPy 中实际发生的工作。
如果 NumPy 提供的操作太有限而无法根据它们重写 generate
,可以选择使用 Cython 重写 generate
,或使用 @numba.jit
就可以了。这些主要有助于涉及从一个循环迭代到下一个循环迭代的复杂依赖关系的计算;它们对您无法重写的外部依赖项没有帮助。
如果您无法重写generate
,您所能做的就是尝试优化将返回值放入数组的过程。根据数组大小,您可以通过重复使用单个数组对象来节省一些时间:
In [32]: %timeit x = numpy.array([random.random() for _ in range(10)])
The slowest run took 5.13 times longer than the fastest. This could mean that an
intermediate result is being cached.
100000 loops, best of 5: 5.44 µs per loop
In [33]: %%timeit x = numpy.empty(10)
....: for i in range(10):
....: x[i] = random.random()
....:
The slowest run took 4.26 times longer than the fastest. This could mean that an
intermediate result is being cached.
100000 loops, best of 5: 2.88 µs per loop
但是对于更大的数组,好处就消失了:
In [34]: %timeit x = numpy.array([random.random() for _ in range(100)])
10000 loops, best of 5: 21.9 µs per loop
In [35]: %%timeit x = numpy.empty(100)
....: for i in range(100):
....: x[i] = random.random()
....:
10000 loops, best of 5: 22.8 µs per loop
关于python - 如何使用来自对函数的单独调用的值快速填充 numpy 数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55630612/