如何将多输入函数向量化,生成仅接收t参数的信号函数?
问题描述
我有如下形式的信号原型函数:
def signal_prototype(t, A, f, p): return A*np.sin(2*np.pi*f*t+p)
我希望生成 signal_A、signal_B 等专用信号函数,使用方式如下:
signal_A = SOME_FUNCTION(signal_prototype, A=1, f=10000, p=0) signal_B = SOME_FUNCTION(signal_prototype, A=1, f=10000, p=np.pi/4) signal_C = SOME_FUNCTION(signal_prototype, A=1, f=10000, p=np.pi/2) signal_D = SOME_FUNCTION(signal_prototype, 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,但没法传入固定参数,而且它可能不是最优方案。这些信号要作为复杂微分方程的输入,需要是仅接受t的函数形式;同时模型条件会动态变化,没法创建静态版本的函数。
解决方案
你需要的是绑定固定参数生成新函数的能力,而非向量化工具,以下两种方案高效且适配你的需求:
方案1:使用functools.partial(推荐)
functools.partial是Python标准库中专门用于绑定函数参数的工具,性能远优于np.vectorize:
import numpy as np from functools import partial def signal_prototype(t, A, f, p): return A*np.sin(2*np.pi*f*t+p) # 绑定固定参数,生成仅接受t的信号函数 signal_A = partial(signal_prototype, A=1, f=10000, p=0) signal_B = partial(signal_prototype, A=1, f=10000, p=np.pi/4) signal_C = partial(signal_prototype, A=1, f=10000, p=np.pi/2) signal_D = partial(signal_prototype, 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)
方案2:自定义封装函数
如果需要更灵活的逻辑控制,可以自己写一个简单的封装函数:
import numpy as np def signal_prototype(t, A, f, p): return A*np.sin(2*np.pi*f*t+p) def create_signal_func(prototype, **fixed_params): def signal_func(t): return prototype(t, **fixed_params) return signal_func # 生成专用信号函数 signal_A = create_signal_func(signal_prototype, A=1, f=10000, p=0) signal_B = create_signal_func(signal_prototype, A=1, f=10000, p=np.pi/4) # 测试 t = np.linspace(0,1e-3,100000) X1 = signal_A(t)
重要说明
np.vectorize的作用是将仅处理标量的函数包装成能处理数组的函数,本质是循环,性能差,和你需要的“绑定固定参数”完全不是一个场景,不建议使用。- 上面两种方案生成的函数都原生支持numpy数组输入,返回数组结果,完全满足微分方程对性能的要求。
- 当模型条件变化时,只需重新调用
partial或create_signal_func生成新函数即可,无需修改原型函数。
内容的提问来源于stack exchange,提问作者Kris Jensen
相关产品推荐
相关产品推荐

