我有一个采用这种形式的函数:
def signal_prototype(t, A, f, p):
return A*np.sin(2*np.pi*f*t+p)
我想对其进行矢量化,以便我可以按如下方式使用该函数。
signal_A = SOME_VECTORIZE_FUNCTION(signal_prototype, t=t, A=1, f=10000, p=0)
signal_B = SOME_VECTORIZE_FUNCTION(signal_prototype, t=t, A=1, f=10000, p=np.pi/4)
signal_C = SOME_VECTORIZE_FUNCTION(signal_prototype, t=t, A=1, f=10000, p=np.pi/2)
signal_D = SOME_VECTORIZE_FUNCTION(signal_prototype, t=t, A=1, f=10000, p=3*np.pi/4)
t = np.linspace(0,1e-3,100000)
X1 = signal_A(t)
X2 = signal_B(t)
X3 = signal_C(t)
X4 = signal_D(t)
谢谢!
我尝试使用
np.vectorize
并阅读文档。似乎没有任何方法可以将静态参数发送到矢量化。
但是,矢量化可能不是最好的工具。
我有一组复杂的微分方程,这些信号是它们的输入。所以,我需要 f(t,x) 形式的函数。
随着模型条件的变化动态创建新的信号函数。因此,创建每个方程的静态版本并不是一个好的选择。
np.sin()
已经矢量化,因为它将在数组上工作
>>> np.sin(np.array([1,2,3]))
array([0.84147098, 0.90929743, 0.14112001])
您可以直接调用您的函数
def signal_prototype(t, A, f, p):
return A*np.sin(2*np.pi*f*t+p)
t = np.linspace(0,1e-3,100000)
X1 = signal_prototype(t=t, A=1, f=10000, p=0)
X2 = signal_prototype(t=t, A=1, f=10000, p=np.pi/4)
X3 = signal_prototype(t=t, A=1, f=10000, p=np.pi/2)
X4 = signal_prototype(t=t, A=1, f=10000, p=3*np.pi/4)
如果您想为每个函数创建一个函数,您可以按照建议使用
lambda
或 functools.partial
signal_A = lambda t: signal_prototype(t=t, A=1, f=10000, p=0)
signal_B = lambda t: signal_prototype(t=t, A=1, f=10000, p=np.pi/4)
signal_C = lambda t: signal_prototype(t=t, A=1, f=10000, p=np.pi/2)
signal_D = lambda t: signal_prototype(t=t, A=1, f=10000, p=3*np.pi/4)
X1 = signal_A(t)
X2 = signal_B(t)
X3 = signal_C(t)
X4 = signal_D(t)
或者自己返回部分函数(实际上与
lambda
相同)
def wrapper(func, **kwargs):
def wrapped(t):
return func(t, **kwargs)
return wrapped
signal_A = wrapper(signal_prototype, A=1, f=10000, p=0)
signal_B = wrapper(signal_prototype, A=1, f=10000, p=np.pi/4)
signal_C = wrapper(signal_prototype, A=1, f=10000, p=np.pi/2)
signal_D = wrapper(signal_prototype, A=1, f=10000, p=3*np.pi/4)
如果你想传递默认值
t
或使其成为可选的,你可以扩展它,尽管我不建议这样做,只是用它来说明它有多么强大,因为永远不建议返回不同类型的东西(例如作为一个具有可变数量参数的函数)
不要这样做
def wrapper(func, t=None, **kwargs):
if t is not None:
def wrapped(t=t):
return func(t, **kwargs)
else:
def wrapped(t):
return func(t, **kwargs)
return wrapped
>>> wrapper(signal_prototype, A=1, f=10000, p=0)(t)
array([ 0.00000000e+00, 6.28324773e-04, 1.25664930e-03, ...,
-1.25664930e-03, -6.28324773e-04, -2.44929360e-15])
>>> wrapper(signal_prototype, t=t, A=1, f=10000, p=0)()
array([ 0.00000000e+00, 6.28324773e-04, 1.25664930e-03, ...,
-1.25664930e-03, -6.28324773e-04, -2.44929360e-15])
上面的答案确实帮助我弄清楚了我需要做什么。
X1 = partial(signal_prototype, A=1e-3, f=1e3, p=0)
X2 = partial(signal_prototype, A=1e-3, f=1e3, p=np.pi/4)
X3 = partial(signal_prototype, A=1e-3, f=1e3, p=np.pi/2)
X4 = partial(signal_prototype, A=1e-3, f=1e3, p=3*np.pi/4)
现在我有了可以像这样调用的函数。
X1(t)
X2(t)
etc...