如何有效地向量化函数并从中检索值
how to efficiently vectorize a function and retrieve values from it
假设我有一个计算量很大的函数f(x)
。我想计算它的一些值,然后只访问它们而不是每次都使用新的 x
值评估函数。
请参阅以下简单示例来说明我的意思:
import numpy as np
x = np.linspace(-3, 3, 6001)
fx = x**2
x = np.round(x, 3)
#I want to evaluate the function for the following w:
w = np.random.rand(10000)
#Rounding is necessary, so that the w match the x.
w = np.round(w, 3)
fx_w = []
for i in range(w.size):
fx_w.append(fx[x==w[i]])
fx_w = np.asarray(fx_w)
所以,我想根据 x
已经生成的值计算 f(w)
。当然,for
循环是不可能的,所以我的问题是:我怎样才能稍微有效地实现它?
您可以使用searchsorted
找到您准备好的函数数组的对应索引。这将是一个近似值。不需要四舍五入。
import numpy as np
np.random.seed(42)
x = np.linspace(-3, 3, 6001)
fx = x ** 2
w = np.random.rand(10000)
result = fx[np.searchsorted(x, w)]
print('aprox. F(x):', result)
print('real F(x):', w ** 2)
输出
aprox. F(x): [0.140625 0.904401 0.535824 ... 0.896809 0.158404 0.047524 ]
real F(x): [0.1402803 0.90385769 0.53581513 ... 0.89625588 0.1579967 0.04714996]
您的函数必须具有更高的计算强度才能证明这种方法的合理性
%timeit fx[np.searchsorted(x, w)] #1000 loops, best of 5: 992 µs per loop
%timeit w ** 2 #100000 loops, best of 5: 3.81 µs per loop
假设我有一个计算量很大的函数f(x)
。我想计算它的一些值,然后只访问它们而不是每次都使用新的 x
值评估函数。
请参阅以下简单示例来说明我的意思:
import numpy as np
x = np.linspace(-3, 3, 6001)
fx = x**2
x = np.round(x, 3)
#I want to evaluate the function for the following w:
w = np.random.rand(10000)
#Rounding is necessary, so that the w match the x.
w = np.round(w, 3)
fx_w = []
for i in range(w.size):
fx_w.append(fx[x==w[i]])
fx_w = np.asarray(fx_w)
所以,我想根据 x
已经生成的值计算 f(w)
。当然,for
循环是不可能的,所以我的问题是:我怎样才能稍微有效地实现它?
您可以使用searchsorted
找到您准备好的函数数组的对应索引。这将是一个近似值。不需要四舍五入。
import numpy as np
np.random.seed(42)
x = np.linspace(-3, 3, 6001)
fx = x ** 2
w = np.random.rand(10000)
result = fx[np.searchsorted(x, w)]
print('aprox. F(x):', result)
print('real F(x):', w ** 2)
输出
aprox. F(x): [0.140625 0.904401 0.535824 ... 0.896809 0.158404 0.047524 ]
real F(x): [0.1402803 0.90385769 0.53581513 ... 0.89625588 0.1579967 0.04714996]
您的函数必须具有更高的计算强度才能证明这种方法的合理性
%timeit fx[np.searchsorted(x, w)] #1000 loops, best of 5: 992 µs per loop
%timeit w ** 2 #100000 loops, best of 5: 3.81 µs per loop