为何自定义avg_aft_max函数仅在绘图时直接调用才生效?
问题描述
我编写了avg_aft_max函数,用于将信号首个最大值出现后的所有值规整为固定值。但调用该函数并将结果存储到变量后绘图,无法得到预期效果;直接在绘图参数中调用该函数则可正常生成预期图。
函数代码
import math import numpy as np def avg_aft_max(signal): ind = [i for i, value in enumerate(signal) if math.isclose(value, np.max(signal))][0] avg = np.mean(signal[ind:]) signal_new = signal signal_new[ind:] = [np.max(signal) if math.isclose(avg, np.max(signal), rel_tol=1e-3) else np.max(signal) - 5e-12] * len(signal[ind:]) return signal_new
主脚本代码
clamp_data_filtered = avg_aft_max(clamp_data.v) fig.add_trace( go.Scattergl( x=pins_position_slr_takeover.v, y=clamp_data_filtered, # 此方式无效 # y = avg_aft_max(clamp_data.v), # 此方式有效 name=clamp_name + '_Filtered', mode="markers+lines", line=dict(width=4), ), secondary_y=False, row=1, col=1, )
效果对比
- 预期效果:信号在首个最大值出现后,后续所有值被规整为固定值,曲线保持平稳
- 实际效果:信号在最大值出现后仍存在波动,未被正确规整为固定值
问题原因与解决方案
问题根源
函数中signal_new = signal是引用赋值(针对numpy数组),而非创建新的副本。这意味着修改signal_new时会直接改动原输入数组clamp_data.v。当你先将函数结果存入clamp_data_filtered,原数组已经被修改,后续绘图时使用的变量其实和原数组指向同一内存空间,引发绘图异常;而直接在绘图参数中调用函数时,每次都会基于原数组的初始状态处理,因此能得到正确结果。
修复方案
修改函数中创建新数组的方式,显式复制原数组:
import math import numpy as np def avg_aft_max(signal): ind = [i for i, value in enumerate(signal) if math.isclose(value, np.max(signal))][0] avg = np.mean(signal[ind:]) # 显式创建原数组的副本,避免修改原数据 signal_new = signal.copy() signal_new[ind:] = [np.max(signal) if math.isclose(avg, np.max(signal), rel_tol=1e-3) else np.max(signal) - 5e-12] * len(signal[ind:]) return signal_new
额外优化建议
- 查找首个最大值索引时,用numpy的
argmax更高效:ind = np.argmax(signal)(若存在多个相同最大值,argmax会返回第一个出现的索引,和原逻辑一致) - 赋值固定值时无需生成列表,直接用标量赋值更高效
优化后的函数:
import math import numpy as np def avg_aft_max(signal): max_val = np.max(signal) ind = np.argmax(signal) avg = np.mean(signal[ind:]) signal_new = signal.copy() fill_val = max_val if math.isclose(avg, max_val, rel_tol=1e-3) else max_val - 5e-12 signal_new[ind:] = fill_val return signal_new
内容的提问来源于stack exchange,提问作者Praveen Kumar Pakkirisamy
相关产品推荐
相关产品推荐

