Python 如何用单独调用函数的值快速填充numpy数组

Python 如何用单独调用函数的值快速填充numpy数组,python,python-3.x,numpy,Python,Python 3.x,Numpy,我想用生成的值填充numpy数组。这些值由生成器函数生成。数组长度不太长,传统的“Pythoninc” ,或者两者都可能是您的解决方案: from random import random import numpy as np np.array(list(map(lambda idx: random(), range(10)))) np.array([random() for idx in range(10)]) “对速度的需求” 也许预先分配内存会减少一两微秒(?) 请参阅以获得更好的解决

我想用生成的值填充numpy数组。这些值由生成器函数生成。数组长度不太长,传统的“Pythoninc” ,或者两者都可能是您的解决方案:

from random import random
import numpy as np

np.array(list(map(lambda idx: random(), range(10))))
np.array([random() for idx in range(10)])
“对速度的需求” 也许预先分配内存会减少一两微秒(?)

请参阅以获得更好的解决方案

功能矢量化 可以使用numpy对函数进行“矢量化”:

def rnd(x):
    return random()

fun = np.vectorize(rnd)
array = fun(range(10))

另一个选项是从
generate
函数生成
ufunc

gen_array=np.frompyfunc(generate,0,1)#接受0个参数,返回1
array=gen_数组(np.empty(数组长度))

对我来说,这比来自的“速度需求”版本快了一点。

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

它应该是
np.array(list(map(lambda idx:random(),range(10)))
或者它不起作用。如果您理解正确,我现在就去测试它,看看它是否更快。实际上更多的是关于代码的清洁度。我希望会有一些优雅的numpy功能来做这件事。它实际上已经足够快了,但我只是想学习一些numpy技巧,这对代码可读性和性能都有好处。(使用列表(map())实际上要慢一些)最后一个是我用np.vectorize()尝试的。但是和其他的相比,它的速度非常慢。使用
[random()for uuu in range(10)]
创建1000000个数组约3.8秒,使用
列表(map(lambda))
创建约4.6秒,使用
np.vectorize()
创建约58.5秒我也遇到过“vectorize”函数的问题,但我不知道如何加快速度……没关系,您的“速度需求”解决方案实际上非常快,使用了与之前测试相同的参数。只需约1.9秒,我将为您的努力进行投票,谢谢:)谢谢,我喜欢该解决方案,但我生成的值是序列,所以遗憾的是,它在我的情况下不起作用。谢谢您提供的信息,“NumPy只能加速在NumPy中实际发生的工作。”这实际上解释了为什么我没有找到更好的方法,所以我只保留我的代码。事实上,它已经足够快了,而且在我看来是可读的。
def rnd(x):
    return random()

fun = np.vectorize(rnd)
array = fun(range(10))
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