在numpy数组上映射函数的最有效方法是什么?我目前正在做:

import numpy as np 

x = np.array([1, 2, 3, 4, 5])

# Obtain array of square of each element in x
squarer = lambda t: t ** 2
squares = np.array([squarer(xi) for xi in x])

然而,这可能非常低效,因为我在将新数组转换回numpy数组之前,使用列表推导式将其构造为Python列表。我们能做得更好吗?


当前回答

我相信在numpy的新版本(我使用1.13)中,您可以简单地通过将numpy数组传递给您为标量类型编写的函数来调用该函数,它将自动应用函数调用到numpy数组上的每个元素,并返回另一个numpy数组

>>> import numpy as np
>>> squarer = lambda t: t ** 2
>>> x = np.array([1, 2, 3, 4, 5])
>>> squarer(x)
array([ 1,  4,  9, 16, 25])

其他回答

我相信在numpy的新版本(我使用1.13)中,您可以简单地通过将numpy数组传递给您为标量类型编写的函数来调用该函数,它将自动应用函数调用到numpy数组上的每个元素,并返回另一个numpy数组

>>> import numpy as np
>>> squarer = lambda t: t ** 2
>>> x = np.array([1, 2, 3, 4, 5])
>>> squarer(x)
array([ 1,  4,  9, 16, 25])

就像在这篇文章中提到的,像这样使用生成器表达式:

numpy.fromiter((<some_func>(x) for x in <something>),<dtype>,<size of something>)

使用numpy.fromfunction(function, shape, **kwargs)

看到“https://docs.scipy.org/doc/numpy/reference/generated/numpy.fromfunction.html”

使用numpy.vectorize怎么样?

import numpy as np
x = np.array([1, 2, 3, 4, 5])
squarer = lambda t: t ** 2
vfunc = np.vectorize(squarer)
vfunc(x)
# Output : array([ 1,  4,  9, 16, 25])

似乎没有人提到在numpy包中生成ufunc的内置工厂方法:np.frompyfunc,我已经对np进行了测试。矢量化,并且比它的表现好大约20~30%。当然,它不能像规定的C代码或numba(我没有测试过)那样执行,但它是比np.vectorize更好的选择

f = lambda x, y: x * y
f_arr = np.frompyfunc(f, 2, 1)
vf = np.vectorize(f)
arr = np.linspace(0, 1, 10000)

%timeit f_arr(arr, arr) # 307ms
%timeit vf(arr, arr) # 450ms

我也测试了更大的样本,改进是成比例的。请在这里查看文档