如何对pandas DataFrame每列应用不同时间常数的一阶滤波器
实现思路与代码示例
首先一阶低通滤波器(增益为1、时间常数tau)的离散实现核心是递推公式:y[n] = α * x[n] + (1-α) * y[n-1],其中α = 采样间隔dt / (tau + dt),dt为数据的采样间隔,等于1/采样频率fs。
对应多列不同参数的实现步骤如下:
步骤1:准备列与时间常数的映射关系
用字典存储每列对应的时间常数,方便后续遍历调用:
tau_map = { "Column_A": 5, "Column_B": 15, "Column_C": 60, "Column_D": 200 }
步骤2:确定采样参数
根据你的数据实际采样频率计算采样间隔:
fs = 1 # 替换为你的实际采样率,单位Hz dt = 1 / fs
步骤3:滤波实现
提供两种常用实现方式,可按需选择:
方式1:手动实现(无额外依赖)
适合不想引入scipy依赖的场景,逻辑透明:
import numpy as np import pandas as pd def first_order_filter(x, tau, dt): alpha = dt / (tau + dt) y = np.zeros_like(x, dtype=np.float64) y[0] = x[0] # 初始值取第一个采样点,也可自定义为前N点均值减少起始波动 for n in range(1, len(x)): y[n] = alpha * x[n] + (1 - alpha) * y[n-1] return y # 逐列应用滤波 filtered_df = pd.DataFrame() for col, tau in tau_map.items(): filtered_df[col] = first_order_filter(df[col].values, tau, dt)
方式2:基于scipy实现(效率更高)
调用scipy的lfilter方法,长序列处理速度更快:
from scipy import signal def scipy_first_order_filter(x, tau, dt): alpha = dt / (tau + dt) b = [alpha] a = [1, -(1 - alpha)] return signal.lfilter(b, a, x) # 逐列应用滤波 filtered_df = pd.DataFrame() for col, tau in tau_map.items(): filtered_df[col] = scipy_first_order_filter(df[col].values, tau, dt)
注意事项
- 提前对原始数据的缺失值做填充/删除处理,否则滤波会输出异常值
- 若需要消除滤波带来的相位延迟,可以替换为双向滤波
signal.filtfilt实现零相位滤波 - 采样间隔dt必须和实际数据匹配,否则时间常数的滤波效果会出现偏差
内容的提问来源于stack exchange,提问作者User365Go
相关产品推荐
相关产品推荐

