Python实战用零阶保持器搞定信号采样与恢复附完整代码在数字信号处理的世界里采样与恢复是两个最基础却至关重要的环节。想象一下当你用手机录制一段音乐或者通过传感器采集温度数据时这些连续的模拟信号是如何变成计算机能够处理的数字信号的又如何在需要时重新还原为连续信号这正是我们今天要探讨的核心问题。零阶保持器Zero-Order Hold, ZOH作为信号恢复中最常用的方法之一它的原理简单却效果显著。不同于复杂的数学插值方法ZOH通过保持采样点的值直到下一个采样时刻到来实现了离散信号到连续信号的转换。这种方法在数字控制系统、音频处理和通信系统中有着广泛应用。本文将带你用Python从零开始实现信号采样与恢复的完整流程。我们会从香农采样定理出发通过可视化对比不同采样频率下的信号恢复效果直观理解混叠现象的产生原因。最后你将获得一套可直接复用的代码能够应用于你自己的信号处理项目中。1. 理论基础与准备工作1.1 理解香农采样定理香农采样定理又称奈奎斯特采样定理是信号处理领域的基石。它告诉我们要无失真地从采样信号中恢复原始连续信号采样频率必须至少是信号最高频率的两倍。数学表达式为fs 2 * fmax其中fs采样频率Hzfmax信号中的最高频率成分Hz当这个条件不满足时就会出现混叠Aliasing现象——高频信号被错误地表现为低频信号。这种现象在现实生活中也很常见比如旋转的车轮看起来在倒转就是视觉上的混叠效应。1.2 零阶保持器的工作原理零阶保持器是最简单的信号重建方法它的工作方式可以用一句话概括保持当前采样值直到下一个采样时刻。数学上这相当于对采样信号进行矩形窗卷积。与理想重建使用sinc函数插值相比ZOH虽然会引入高频分量和相位延迟但它有两大优势实现简单计算量小硬件实现成本低在实际系统中ZOH之后通常会接一个低通滤波器以平滑输出信号。1.3 Python环境配置在开始编码前确保你的Python环境已安装以下库pip install numpy matplotlib scipy这些库将帮助我们numpy进行高效的数值计算matplotlib数据可视化scipy科学计算辅助功能为了后续代码的顺利运行我们先进行基础配置import numpy as np import matplotlib.pyplot as plt from scipy import signal # 设置中文显示和负号显示 plt.rcParams[font.family] [SimHei] # 中文显示 plt.rcParams[axes.unicode_minus] False # 解决负号显示问题2. 信号采样实现2.1 构建测试信号我们首先创建一个包含多个频率成分的复合信号作为测试对象def create_test_signal(t, frequencies[1, 3], amplitudes[1, 0.5]): 创建多频复合信号 参数: t: 时间数组 frequencies: 各频率成分列表 (Hz) amplitudes: 对应振幅列表 返回: 复合信号值数组 signal_component [amp * np.sin(2 * np.pi * freq * t) for freq, amp in zip(frequencies, amplitudes)] return np.sum(signal_component, axis0)这个函数可以生成由多个正弦波叠加而成的信号。默认情况下我们创建一个包含1Hz振幅1和3Hz振幅0.5成分的信号。2.2 采样函数实现采样过程的本质是在连续时间轴上按固定间隔提取信号值。以下是采样函数的实现def sample_signal(continuous_time, continuous_signal, fs): 对连续信号进行采样 参数: continuous_time: 连续时间数组 continuous_signal: 连续信号值数组 fs: 采样频率 (Hz) 返回: sampled_time: 采样时间点数组 sampled_signal: 采样信号值数组 Ts 1 / fs # 采样周期 n_samples int((continuous_time[-1] - continuous_time[0]) / Ts) 1 sampled_time np.linspace(continuous_time[0], continuous_time[-1], n_samples) sampled_signal np.interp(sampled_time, continuous_time, continuous_signal) return sampled_time, sampled_signal这个函数首先计算采样周期Ts然后确定采样点数最后通过线性插值获取采样时刻的信号值。2.3 采样频率对比实验为了直观理解采样频率的影响我们设置三个不同的采样频率进行对比# 生成连续信号 t_continuous np.linspace(0, 2, 1000) # 2秒时长1000个点 signal_continuous create_test_signal(t_continuous) # 不同采样频率 sampling_rates [5, 10, 20] # Hz plt.figure(figsize(12, 8)) # 绘制原始信号 plt.subplot(len(sampling_rates)1, 1, 1) plt.plot(t_continuous, signal_continuous, b-, linewidth2) plt.title(原始连续信号 (1Hz 3Hz)) plt.grid(True) # 绘制不同采样率下的采样结果 for i, fs in enumerate(sampling_rates): t_sampled, signal_sampled sample_signal(t_continuous, signal_continuous, fs) plt.subplot(len(sampling_rates)1, 1, i2) plt.plot(t_continuous, signal_continuous, b-, alpha0.3, label原始信号) plt.stem(t_sampled, signal_sampled, r, markerfmtro, basefmt , label采样信号) plt.title(f采样频率 {fs}Hz ({满足 if fs 6 else 不满足}香农定理)) plt.grid(True) plt.legend() plt.tight_layout() plt.show()运行这段代码你会看到三组对比图。注意3Hz信号的奈奎斯特频率是6Hz所以5Hz采样不满足香农定理会出现混叠10Hz和20Hz采样满足香农定理能较好保留信号特征3. 零阶保持器实现3.1 ZOH核心算法零阶保持器的实现逻辑相当直接def zero_order_hold(sampled_time, sampled_signal, output_time): 零阶保持器实现 参数: sampled_time: 采样时间数组 sampled_signal: 采样信号值数组 output_time: 输出时间数组 返回: 重建后的连续信号 reconstructed np.zeros_like(output_time) for i in range(len(sampled_time)-1): # 找到位于当前采样点和下一个采样点之间的所有时间点 mask (output_time sampled_time[i]) (output_time sampled_time[i1]) reconstructed[mask] sampled_signal[i] # 处理最后一个采样点之后的部分 reconstructed[output_time sampled_time[-1]] sampled_signal[-1] return reconstructed这个函数遍历每个采样间隔将采样值保持到下一个采样时刻从而重建出阶梯状的连续信号。3.2 信号恢复效果对比现在我们将采样和恢复过程结合起来观察不同采样频率下的恢复效果plt.figure(figsize(12, 10)) for i, fs in enumerate(sampling_rates): # 采样 t_sampled, signal_sampled sample_signal(t_continuous, signal_continuous, fs) # 零阶保持恢复 signal_reconstructed zero_order_hold(t_sampled, signal_sampled, t_continuous) # 计算恢复误差 error signal_continuous - signal_reconstructed # 绘制结果 plt.subplot(len(sampling_rates), 1, i1) plt.plot(t_continuous, signal_continuous, b-, alpha0.5, label原始信号) plt.stem(t_sampled, signal_sampled, r, markerfmtro, basefmt , linefmtr-, label采样点) plt.plot(t_continuous, signal_reconstructed, g-, labelZOH恢复信号) plt.fill_between(t_continuous, signal_reconstructed, signal_continuous, coloryellow, alpha0.3, label误差区域) plt.title(f采样频率{fs}Hz, RMSE{np.sqrt(np.mean(error**2)):.4f}) plt.legend() plt.grid(True) plt.tight_layout() plt.show()从结果中可以观察到采样频率越高恢复信号与原始信号的误差越小即使采样频率满足香农定理ZOH恢复的信号仍有高频失真5Hz采样时高频成分(3Hz)出现严重混叠3.3 频域分析为了更深入地理解ZOH的影响我们进行频域分析def plot_frequency_response(signal, fs, title): 绘制信号频谱 n len(signal) freq np.fft.fftfreq(n, d1/fs) fft_vals np.fft.fft(signal) magnitude np.abs(fft_vals)[:n//2] freq freq[:n//2] plt.figure(figsize(10, 4)) plt.stem(freq, magnitude, b, markerfmtbo, basefmt ) plt.title(title) plt.xlabel(频率 (Hz)) plt.ylabel(幅度) plt.grid(True) plt.xlim([0, 10]) # 原始信号频谱 plot_frequency_response(signal_continuous, 1000, 原始信号频谱) # 5Hz采样恢复信号的频谱 _, signal_5hz sample_signal(t_continuous, signal_continuous, 5) reconstructed_5hz zero_order_hold(t_sampled, signal_5hz, t_continuous) plot_frequency_response(reconstructed_5hz, 1000, 5Hz采样ZOH恢复信号频谱) # 20Hz采样恢复信号的频谱 _, signal_20hz sample_signal(t_continuous, signal_continuous, 20) reconstructed_20hz zero_order_hold(t_sampled, signal_20hz, t_continuous) plot_frequency_response(reconstructed_20hz, 1000, 20Hz采样ZOH恢复信号频谱)频域分析揭示了两个关键现象5Hz采样时3Hz信号混叠为2Hz信号5-32ZOH引入了高频谐波分量这些可以通过后续的低通滤波去除4. 实际应用与优化4.1 添加抗混叠滤波器在实际系统中为了避免高频信号混叠到低频通常在采样前会使用抗混叠滤波器低通滤波器。让我们模拟这个过程# 设计抗混叠滤波器 nyquist_rate 10 # 假设采样频率为20Hz cutoff nyquist_rate / 2.5 # 截止频率 b, a signal.butter(4, cutoff / (1000/2), low) # 1000是连续信号的采样率 # 应用滤波器 filtered_signal signal.filtfilt(b, a, signal_continuous) # 采样和重建 t_sampled, signal_sampled sample_signal(t_continuous, filtered_signal, 10) signal_reconstructed zero_order_hold(t_sampled, signal_sampled, t_continuous) # 绘制结果 plt.figure(figsize(12, 5)) plt.plot(t_continuous, signal_continuous, b-, alpha0.3, label原始信号) plt.plot(t_continuous, filtered_signal, c-, alpha0.6, label滤波后信号) plt.stem(t_sampled, signal_sampled, r, markerfmtro, basefmt , label采样点) plt.plot(t_continuous, signal_reconstructed, g-, labelZOH恢复信号) plt.title(使用抗混叠滤波器的采样与恢复) plt.legend() plt.grid(True) plt.show()可以看到抗混叠滤波器有效去除了高于奈奎斯特频率的成分减少了混叠失真。4.2 后置低通滤波优化为了改善ZOH输出的阶梯状波形我们可以在恢复后添加一个低通滤波器# ZOH恢复 signal_reconstructed zero_order_hold(t_sampled, signal_sampled, t_continuous) # 设计后置滤波器 post_cutoff nyquist_rate / 2 b_post, a_post signal.butter(4, post_cutoff / (1000/2), low) # 应用后置滤波 smoothed_signal signal.filtfilt(b_post, a_post, signal_reconstructed) # 绘制结果 plt.figure(figsize(12, 5)) plt.plot(t_continuous, signal_continuous, b-, alpha0.3, label原始信号) plt.plot(t_continuous, signal_reconstructed, g-, alpha0.5, labelZOH恢复) plt.plot(t_continuous, smoothed_signal, m-, linewidth2, label平滑后信号) plt.title(ZOH恢复与后置滤波效果对比) plt.legend() plt.grid(True) plt.show()后置滤波有效平滑了ZOH输出的阶梯波形更接近原始连续信号。4.3 性能指标量化为了客观评估不同配置下的恢复质量我们引入几个量化指标指标名称计算公式说明RMSE$\sqrt{\frac{1}{N}\sum(y-y_{true})^2}$均方根误差峰值误差$\max(y-y_{true}相关系数$\frac{\text{cov}(y,y_{true})}{\sigma_y \sigma_{y_{true}}}$波形相似度计算这些指标的函数实现def evaluate_reconstruction(original, reconstructed): 评估信号恢复质量 返回包含各项指标的字典 error original - reconstructed metrics { RMSE: np.sqrt(np.mean(error**2)), Peak_Error: np.max(np.abs(error)), Correlation: np.corrcoef(original, reconstructed)[0, 1], SNR: 10 * np.log10(np.var(original) / np.var(error)) } return metrics # 测试不同采样频率下的指标 results [] for fs in [5, 10, 20, 40]: t_sampled, signal_sampled sample_signal(t_continuous, signal_continuous, fs) reconstructed zero_order_hold(t_sampled, signal_sampled, t_continuous) metrics evaluate_reconstruction(signal_continuous, reconstructed) metrics[Sampling_Rate] fs results.append(metrics) # 展示结果 import pandas as pd df_results pd.DataFrame(results) print(df_results[[Sampling_Rate, RMSE, Peak_Error, Correlation, SNR]])从量化结果可以清晰看到随着采样频率提高所有指标都有显著改善。特别是当采样频率达到信号最高频率的4倍(12Hz)以上时恢复质量趋于稳定。
Python实战:用零阶保持器搞定信号采样与恢复(附完整代码)
Python实战用零阶保持器搞定信号采样与恢复附完整代码在数字信号处理的世界里采样与恢复是两个最基础却至关重要的环节。想象一下当你用手机录制一段音乐或者通过传感器采集温度数据时这些连续的模拟信号是如何变成计算机能够处理的数字信号的又如何在需要时重新还原为连续信号这正是我们今天要探讨的核心问题。零阶保持器Zero-Order Hold, ZOH作为信号恢复中最常用的方法之一它的原理简单却效果显著。不同于复杂的数学插值方法ZOH通过保持采样点的值直到下一个采样时刻到来实现了离散信号到连续信号的转换。这种方法在数字控制系统、音频处理和通信系统中有着广泛应用。本文将带你用Python从零开始实现信号采样与恢复的完整流程。我们会从香农采样定理出发通过可视化对比不同采样频率下的信号恢复效果直观理解混叠现象的产生原因。最后你将获得一套可直接复用的代码能够应用于你自己的信号处理项目中。1. 理论基础与准备工作1.1 理解香农采样定理香农采样定理又称奈奎斯特采样定理是信号处理领域的基石。它告诉我们要无失真地从采样信号中恢复原始连续信号采样频率必须至少是信号最高频率的两倍。数学表达式为fs 2 * fmax其中fs采样频率Hzfmax信号中的最高频率成分Hz当这个条件不满足时就会出现混叠Aliasing现象——高频信号被错误地表现为低频信号。这种现象在现实生活中也很常见比如旋转的车轮看起来在倒转就是视觉上的混叠效应。1.2 零阶保持器的工作原理零阶保持器是最简单的信号重建方法它的工作方式可以用一句话概括保持当前采样值直到下一个采样时刻。数学上这相当于对采样信号进行矩形窗卷积。与理想重建使用sinc函数插值相比ZOH虽然会引入高频分量和相位延迟但它有两大优势实现简单计算量小硬件实现成本低在实际系统中ZOH之后通常会接一个低通滤波器以平滑输出信号。1.3 Python环境配置在开始编码前确保你的Python环境已安装以下库pip install numpy matplotlib scipy这些库将帮助我们numpy进行高效的数值计算matplotlib数据可视化scipy科学计算辅助功能为了后续代码的顺利运行我们先进行基础配置import numpy as np import matplotlib.pyplot as plt from scipy import signal # 设置中文显示和负号显示 plt.rcParams[font.family] [SimHei] # 中文显示 plt.rcParams[axes.unicode_minus] False # 解决负号显示问题2. 信号采样实现2.1 构建测试信号我们首先创建一个包含多个频率成分的复合信号作为测试对象def create_test_signal(t, frequencies[1, 3], amplitudes[1, 0.5]): 创建多频复合信号 参数: t: 时间数组 frequencies: 各频率成分列表 (Hz) amplitudes: 对应振幅列表 返回: 复合信号值数组 signal_component [amp * np.sin(2 * np.pi * freq * t) for freq, amp in zip(frequencies, amplitudes)] return np.sum(signal_component, axis0)这个函数可以生成由多个正弦波叠加而成的信号。默认情况下我们创建一个包含1Hz振幅1和3Hz振幅0.5成分的信号。2.2 采样函数实现采样过程的本质是在连续时间轴上按固定间隔提取信号值。以下是采样函数的实现def sample_signal(continuous_time, continuous_signal, fs): 对连续信号进行采样 参数: continuous_time: 连续时间数组 continuous_signal: 连续信号值数组 fs: 采样频率 (Hz) 返回: sampled_time: 采样时间点数组 sampled_signal: 采样信号值数组 Ts 1 / fs # 采样周期 n_samples int((continuous_time[-1] - continuous_time[0]) / Ts) 1 sampled_time np.linspace(continuous_time[0], continuous_time[-1], n_samples) sampled_signal np.interp(sampled_time, continuous_time, continuous_signal) return sampled_time, sampled_signal这个函数首先计算采样周期Ts然后确定采样点数最后通过线性插值获取采样时刻的信号值。2.3 采样频率对比实验为了直观理解采样频率的影响我们设置三个不同的采样频率进行对比# 生成连续信号 t_continuous np.linspace(0, 2, 1000) # 2秒时长1000个点 signal_continuous create_test_signal(t_continuous) # 不同采样频率 sampling_rates [5, 10, 20] # Hz plt.figure(figsize(12, 8)) # 绘制原始信号 plt.subplot(len(sampling_rates)1, 1, 1) plt.plot(t_continuous, signal_continuous, b-, linewidth2) plt.title(原始连续信号 (1Hz 3Hz)) plt.grid(True) # 绘制不同采样率下的采样结果 for i, fs in enumerate(sampling_rates): t_sampled, signal_sampled sample_signal(t_continuous, signal_continuous, fs) plt.subplot(len(sampling_rates)1, 1, i2) plt.plot(t_continuous, signal_continuous, b-, alpha0.3, label原始信号) plt.stem(t_sampled, signal_sampled, r, markerfmtro, basefmt , label采样信号) plt.title(f采样频率 {fs}Hz ({满足 if fs 6 else 不满足}香农定理)) plt.grid(True) plt.legend() plt.tight_layout() plt.show()运行这段代码你会看到三组对比图。注意3Hz信号的奈奎斯特频率是6Hz所以5Hz采样不满足香农定理会出现混叠10Hz和20Hz采样满足香农定理能较好保留信号特征3. 零阶保持器实现3.1 ZOH核心算法零阶保持器的实现逻辑相当直接def zero_order_hold(sampled_time, sampled_signal, output_time): 零阶保持器实现 参数: sampled_time: 采样时间数组 sampled_signal: 采样信号值数组 output_time: 输出时间数组 返回: 重建后的连续信号 reconstructed np.zeros_like(output_time) for i in range(len(sampled_time)-1): # 找到位于当前采样点和下一个采样点之间的所有时间点 mask (output_time sampled_time[i]) (output_time sampled_time[i1]) reconstructed[mask] sampled_signal[i] # 处理最后一个采样点之后的部分 reconstructed[output_time sampled_time[-1]] sampled_signal[-1] return reconstructed这个函数遍历每个采样间隔将采样值保持到下一个采样时刻从而重建出阶梯状的连续信号。3.2 信号恢复效果对比现在我们将采样和恢复过程结合起来观察不同采样频率下的恢复效果plt.figure(figsize(12, 10)) for i, fs in enumerate(sampling_rates): # 采样 t_sampled, signal_sampled sample_signal(t_continuous, signal_continuous, fs) # 零阶保持恢复 signal_reconstructed zero_order_hold(t_sampled, signal_sampled, t_continuous) # 计算恢复误差 error signal_continuous - signal_reconstructed # 绘制结果 plt.subplot(len(sampling_rates), 1, i1) plt.plot(t_continuous, signal_continuous, b-, alpha0.5, label原始信号) plt.stem(t_sampled, signal_sampled, r, markerfmtro, basefmt , linefmtr-, label采样点) plt.plot(t_continuous, signal_reconstructed, g-, labelZOH恢复信号) plt.fill_between(t_continuous, signal_reconstructed, signal_continuous, coloryellow, alpha0.3, label误差区域) plt.title(f采样频率{fs}Hz, RMSE{np.sqrt(np.mean(error**2)):.4f}) plt.legend() plt.grid(True) plt.tight_layout() plt.show()从结果中可以观察到采样频率越高恢复信号与原始信号的误差越小即使采样频率满足香农定理ZOH恢复的信号仍有高频失真5Hz采样时高频成分(3Hz)出现严重混叠3.3 频域分析为了更深入地理解ZOH的影响我们进行频域分析def plot_frequency_response(signal, fs, title): 绘制信号频谱 n len(signal) freq np.fft.fftfreq(n, d1/fs) fft_vals np.fft.fft(signal) magnitude np.abs(fft_vals)[:n//2] freq freq[:n//2] plt.figure(figsize(10, 4)) plt.stem(freq, magnitude, b, markerfmtbo, basefmt ) plt.title(title) plt.xlabel(频率 (Hz)) plt.ylabel(幅度) plt.grid(True) plt.xlim([0, 10]) # 原始信号频谱 plot_frequency_response(signal_continuous, 1000, 原始信号频谱) # 5Hz采样恢复信号的频谱 _, signal_5hz sample_signal(t_continuous, signal_continuous, 5) reconstructed_5hz zero_order_hold(t_sampled, signal_5hz, t_continuous) plot_frequency_response(reconstructed_5hz, 1000, 5Hz采样ZOH恢复信号频谱) # 20Hz采样恢复信号的频谱 _, signal_20hz sample_signal(t_continuous, signal_continuous, 20) reconstructed_20hz zero_order_hold(t_sampled, signal_20hz, t_continuous) plot_frequency_response(reconstructed_20hz, 1000, 20Hz采样ZOH恢复信号频谱)频域分析揭示了两个关键现象5Hz采样时3Hz信号混叠为2Hz信号5-32ZOH引入了高频谐波分量这些可以通过后续的低通滤波去除4. 实际应用与优化4.1 添加抗混叠滤波器在实际系统中为了避免高频信号混叠到低频通常在采样前会使用抗混叠滤波器低通滤波器。让我们模拟这个过程# 设计抗混叠滤波器 nyquist_rate 10 # 假设采样频率为20Hz cutoff nyquist_rate / 2.5 # 截止频率 b, a signal.butter(4, cutoff / (1000/2), low) # 1000是连续信号的采样率 # 应用滤波器 filtered_signal signal.filtfilt(b, a, signal_continuous) # 采样和重建 t_sampled, signal_sampled sample_signal(t_continuous, filtered_signal, 10) signal_reconstructed zero_order_hold(t_sampled, signal_sampled, t_continuous) # 绘制结果 plt.figure(figsize(12, 5)) plt.plot(t_continuous, signal_continuous, b-, alpha0.3, label原始信号) plt.plot(t_continuous, filtered_signal, c-, alpha0.6, label滤波后信号) plt.stem(t_sampled, signal_sampled, r, markerfmtro, basefmt , label采样点) plt.plot(t_continuous, signal_reconstructed, g-, labelZOH恢复信号) plt.title(使用抗混叠滤波器的采样与恢复) plt.legend() plt.grid(True) plt.show()可以看到抗混叠滤波器有效去除了高于奈奎斯特频率的成分减少了混叠失真。4.2 后置低通滤波优化为了改善ZOH输出的阶梯状波形我们可以在恢复后添加一个低通滤波器# ZOH恢复 signal_reconstructed zero_order_hold(t_sampled, signal_sampled, t_continuous) # 设计后置滤波器 post_cutoff nyquist_rate / 2 b_post, a_post signal.butter(4, post_cutoff / (1000/2), low) # 应用后置滤波 smoothed_signal signal.filtfilt(b_post, a_post, signal_reconstructed) # 绘制结果 plt.figure(figsize(12, 5)) plt.plot(t_continuous, signal_continuous, b-, alpha0.3, label原始信号) plt.plot(t_continuous, signal_reconstructed, g-, alpha0.5, labelZOH恢复) plt.plot(t_continuous, smoothed_signal, m-, linewidth2, label平滑后信号) plt.title(ZOH恢复与后置滤波效果对比) plt.legend() plt.grid(True) plt.show()后置滤波有效平滑了ZOH输出的阶梯波形更接近原始连续信号。4.3 性能指标量化为了客观评估不同配置下的恢复质量我们引入几个量化指标指标名称计算公式说明RMSE$\sqrt{\frac{1}{N}\sum(y-y_{true})^2}$均方根误差峰值误差$\max(y-y_{true}相关系数$\frac{\text{cov}(y,y_{true})}{\sigma_y \sigma_{y_{true}}}$波形相似度计算这些指标的函数实现def evaluate_reconstruction(original, reconstructed): 评估信号恢复质量 返回包含各项指标的字典 error original - reconstructed metrics { RMSE: np.sqrt(np.mean(error**2)), Peak_Error: np.max(np.abs(error)), Correlation: np.corrcoef(original, reconstructed)[0, 1], SNR: 10 * np.log10(np.var(original) / np.var(error)) } return metrics # 测试不同采样频率下的指标 results [] for fs in [5, 10, 20, 40]: t_sampled, signal_sampled sample_signal(t_continuous, signal_continuous, fs) reconstructed zero_order_hold(t_sampled, signal_sampled, t_continuous) metrics evaluate_reconstruction(signal_continuous, reconstructed) metrics[Sampling_Rate] fs results.append(metrics) # 展示结果 import pandas as pd df_results pd.DataFrame(results) print(df_results[[Sampling_Rate, RMSE, Peak_Error, Correlation, SNR]])从量化结果可以清晰看到随着采样频率提高所有指标都有显著改善。特别是当采样频率达到信号最高频率的4倍(12Hz)以上时恢复质量趋于稳定。