应用scipy滤波函数后保留pandas行号(含NaN)的实现方法
解决Pandas DataFrame中滤波结果与原行号对齐的问题
我来帮你搞定这个滤波结果和原DataFrame行号对齐的问题~你现在的核心困扰是直接删除NaN后处理数据会丢失原始行号,导致滤波后的数组无法对应回原DataFrame的正确位置。只要调整一下处理顺序,先保留原始索引信息,再把滤波结果映射回去就行,具体步骤如下:
核心思路
不要直接删除原DataFrame的NaN行,而是先标记出非NaN的有效行索引,对这些有效数据滤波后,再将结果赋值回原DataFrame的新列中,对应到原来的行号位置,NaN行的新列保持空值即可。
修改后的完整代码
import pandas as pd import numpy as np from scipy import signal from scipy.signal import butter, lfilter probes = {'PT011': [-0.16,-0.162,np.NaN,-0.164,np.NaN,np.NaN,-0.166,-0.167]} df = pd.DataFrame(probes,columns= ['PT011']) print("原始DataFrame:\n", df) # 保留原始DataFrame,不要直接dropna original_df = df.copy() # 提取非NaN的行索引和对应数据 valid_indices = original_df[original_df['PT011'].notna()].index signal_PT011 = original_df.loc[valid_indices, 'PT011'] print("\nType of signal is:\n",type(signal_PT011)) # Pandas series print("signal_PT011:\n",signal_PT011) def butter_lowpass(cutoff, fs, order=2): nyq = 0.5 * fs normal_cutoff = cutoff / nyq b, a = butter(order, normal_cutoff, btype='low', analog=False) return b, a def butter_lowpass_filter(data, cutoff, fs, order=2): b, a = butter_lowpass(cutoff, fs, order=order) y = lfilter(b, a, data) return y order = 2 fs = 100.0 # sample rate, Hz cutoff = 0.5 # desired cutoff frequency of the filter, Hz # 对有效数据进行滤波 signal_PT011_filtered = butter_lowpass_filter(signal_PT011, cutoff, fs, order) print("\nFiltered signal PT011:\n",signal_PT011_filtered) # 创建新列,初始填充NaN original_df['PT011_filtered'] = np.nan # 将滤波结果赋值回对应的原始行号位置 original_df.loc[valid_indices, 'PT011_filtered'] = signal_PT011_filtered # 最终输出对齐后的DataFrame print("\n对齐后的最终DataFrame:\n", original_df)
代码说明
- 我们先复制了原始DataFrame,避免直接修改导致丢失索引信息
- 通过
valid_indices记录了原始DataFrame中所有非NaN的行号 - 滤波完成后,先给原DataFrame新增一列并填充NaN,再用
loc把滤波结果精准赋值到对应的行号位置 - 这样处理后,滤波结果会和原始行号完全对齐,原来的NaN行在新列中依然是NaN,完美匹配你的需求
内容的提问来源于stack exchange,提问作者Tomasz
相关产品推荐
相关产品推荐

