在 numpy 数组上映射函数的最有效方法

新手上路,请多包涵

将函数映射到 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])

但是,这可能效率很低,因为我使用列表推导将新数组构造为 Python 列表,然后再将其转换回 numpy 数组。我们能做得更好吗?

原文由 Ryan 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 676
1 个回答

我已经测试了所有建议的方法加上 np.array(list(map(f, x)))perfplot (我的一个小项目)。

消息 #1:如果您可以使用 numpy 的本机函数,请执行此操作。

如果您尝试矢量化的函数已经 矢量化(如原始帖子中的 x**2 示例),使用它比其他任何方法都 _快得多_(注意对数比例):

在此处输入图像描述

如果您确实需要矢量化,那么使用哪种变体并不重要。

在此处输入图像描述


重现情节的代码:

 import numpy as np
import perfplot
import math

def f(x):
    # return math.sqrt(x)
    return np.sqrt(x)

vf = np.vectorize(f)

def array_for(x):
    return np.array([f(xi) for xi in x])

def array_map(x):
    return np.array(list(map(f, x)))

def fromiter(x):
    return np.fromiter((f(xi) for xi in x), x.dtype)

def vectorize(x):
    return np.vectorize(f)(x)

def vectorize_without_init(x):
    return vf(x)

b = perfplot.bench(
    setup=np.random.rand,
    n_range=[2 ** k for k in range(20)],
    kernels=[
        f,
        array_for,
        array_map,
        fromiter,
        vectorize,
        vectorize_without_init,
    ],
    xlabel="len(x)",
)
b.save("out1.svg")
b.show()

原文由 Nico Schlömer 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题