【发布时间】:2021-04-23 17:07:56
【问题描述】:
对于一个项目,我需要从函数中生成样本。我希望能够尽快生成这些样本。
我有这个例子(在最终版本中,function lambda 将在参数中提供)目标是在 start 和 stop 之间生成行距为 xs 的 n 个点的 ys 使用lambda function。
def get_ys(coefficients, num_outputs=20, start=0., stop=1.):
function = lambda x, args: args[0]*(x-args[1])**2 + args[2]*(x-args[3]) + args[4]
xs = np.linspace(start, stop, num=num_outputs, endpoint=True)
ys = [function(x, coefficients) for x in xs]
return ys
%%time
n = 1000
xs = np.random.random((n,5))
ys = np.apply_along_axis(get_ys, 1, xs)
Wall time: 616 ms
我正在尝试对其进行矢量化,发现numpy.apply_along_axis
%%time
for i in range(1000):
xs = np.random.random(5)
ys = get_ys(xs)
Wall time: 622 ms
不幸的是它仍然很慢:/
我对函数向量化不是很熟悉,有人可以指导我如何提高脚本的速度吗?
谢谢!
编辑: 输入/输出示例:
xs = np.ones(5)
ys = get_ys(xs)
[1.0, 0.9501385041551247, 0.9058171745152355, 0.8670360110803323, 0.8337950138504155,0.8060941828254848, 0.7839335180055402, 0.7673130193905817, 0.7562326869806094, 0.7506925207756232, 0.7506925207756232, 0.7562326869806094, 0.7673130193905817, 0.7839335180055401, 0.8060941828254847, 0.8337950138504155, 0.8670360110803323, 0.9058171745152354, 0.9501385041551246, 1.0]
【问题讨论】:
-
apply_along_axis是一种将仅将 1d 数组转换为 3d(或更大)数组的函数的便捷方式。对于 2d,只在一维上迭代更简单。在任何情况下,它都不是速度工具,因此也不是我们通常所说的“矢量化”。 “矢量化”通常意味着重写您的函数,使其适用于二维数组,利用适用于多维数组的numpy方法。没有捷径可走。你必须学习numpy基础知识。 -
另一种说法 -
apply仍在调用get_ys1000 次。它不会编译它或以其他方式使其更快。 -
@Gulzar,它可以使用给定的代码运行。例如
get_ys(np.arange(5))返回一个包含 20 个值的列表。这不是调试问题,而是重写问题。 -
@hpaulj 哦,我不知道,我以为它会矢量化,我的错。我尝试在函数上使用
numpy.vectorize,但它一次插入一个元素而不是一行,所以我认为我需要使用这个函数.. -
np.vectorize传递标量值,而不是行。它有一个性能免责声明。apply....也应该有一个。
标签: python numpy vectorization