在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)

其他回答

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

numpy.fromiter((<some_func>(x) for x in <something>),<dtype>,<size of something>)
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.fromfunction(function, shape, **kwargs)

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

似乎没有人提到在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的性能结果。