在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列表。我们能做得更好吗?
squares = squarer(x)
数组上的算术运算以元素方式自动应用,高效的c级循环避免了适用于python级循环或理解的所有解释器开销。
您希望应用到NumPy数组elementwise的大多数函数都可以正常工作,尽管有些函数可能需要更改。例如,if不能在元素方面工作。你需要将它们转换为使用numpy.where这样的结构:
def using_if(x):
if x < 5:
return x
else:
return x**2
就变成了
def using_where(x):
return numpy.where(x < 5, x, x**2)
squares = squarer(x)
数组上的算术运算以元素方式自动应用,高效的c级循环避免了适用于python级循环或理解的所有解释器开销。
您希望应用到NumPy数组elementwise的大多数函数都可以正常工作,尽管有些函数可能需要更改。例如,if不能在元素方面工作。你需要将它们转换为使用numpy.where这样的结构:
def using_if(x):
if x < 5:
return x
else:
return x**2
就变成了
def using_where(x):
return numpy.where(x < 5, x, x**2)
似乎没有人提到在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
我也测试了更大的样本,改进是成比例的。请在这里查看文档
编辑:原来的答案是误导性的,np。SQRT直接应用于数组,开销很小。
在多维情况下,您希望应用一个内建函数,操作1d数组numpy。Apply_along_axis是一个不错的选择,对于numpy和scipy中更复杂的函数组合也是如此。
先前的误导性陈述:
添加方法:
def along_axis(x):
return np.apply_along_axis(f, 0, x)
perfplot代码给出接近np.sqrt的性能结果。