如何将100.21Hz信号下采样至8Hz?Python方法适配咨询
当然可以实现100.21Hz到8Hz的下采样!
你的现有代码依赖整数倍间隔采样(idx_range[0::int(sample_rate)/8]),这只适用于采样率是目标倍数整数倍的场景。但100.21/8≈12.526不是整数,直接取整会导致采样率不准,还会引入混叠失真。下面是更可靠的实现方案:
核心思路
- 先做抗混叠滤波:根据奈奎斯特准则,8Hz采样率的奈奎斯特频率是4Hz,必须先把原信号中高于4Hz的频率成分滤除,避免下采样后出现混叠失真。
- 用精准工具重采样:放弃硬间隔取数,改用支持非整数倍转换的工具(比如pandas的
resample或scipy的signal.resample),保证输出严格是8Hz的信号。
改进后的代码
import pandas as pd from scipy.signal import butter, filtfilt def butter_lowpass(cutoff, fs, order=5): nyq = 0.5 * fs normal_cutoff = cutoff / nyq b, a = butter(order, normal_cutoff, btype='low', analog=False) return b, a def lowpass_filter(data, cutoff, fs, order=5): b, a = butter_lowpass(cutoff, fs, order=order) filtered_data = filtfilt(b, a, data, axis=0) return filtered_data def downsampleTo8Hz(data, sample_rate, startTime): # 第一步:给原始数据设置精准的时间索引(匹配100.21Hz采样率) data.index = pd.DatetimeIndex( start=startTime, periods=len(data), freq=pd.Timedelta(seconds=1/sample_rate) ) # 第二步:抗混叠滤波(截止频率设为4Hz,即8Hz的奈奎斯特频率) filtered_data = data.copy() for col in filtered_data.columns: filtered_data[col] = lowpass_filter(filtered_data[col], cutoff=4, fs=sample_rate) # 第三步:重采样到8Hz(125ms间隔)并插值补全 resampled_data = filtered_data.resample('125L').interpolate(method='linear') return resampled_data
关键改进点说明
- 时间索引精准化:原代码直接给采样后的数据套8Hz索引,但原始数据的索引没有对应真实采样时间,改进后先给原始数据建立和100.21Hz匹配的时间序列,保证重采样的时间对齐完全准确。
- 抗混叠滤波:新增的巴特沃斯低通滤波器能有效去除高频噪声,这是下采样的必要步骤——尤其是非整数倍转换时,没滤波很容易出现信号失真。
- 动态重采样:用
resample('125L')替代硬间隔取数,自动处理非整数倍的采样率转换,输出严格是8Hz的时间序列,不用手动计算间隔。
如果你的信号本身已经是低频(比如远低于4Hz),可以跳过滤波步骤,但强烈建议保留,否则容易出现不必要的信号畸变。
内容的提问来源于stack exchange,提问作者machinery
相关产品推荐
相关产品推荐

