通过数据点画一条平滑的线(带过滤器)

Put a smooth line through data points (with filters)

我正在尝试对脉冲图的峰值数据点应用过滤器并使它们平滑,但它似乎不起作用。所需文件 signal.csv

scipy savgol_filter

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from scipy.signal import find_peaks, savgol_filter

df = pd.read_csv('signal.csv')
df.plot(grid = 1,
        c = (0,0,255/255),
        linewidth = 0.5,
        figsize = (10,5),
        legend = False,
        xlim = [df.index[0], df.index[-1]],
        ylim = 0)
plt.xlabel('Zeit / ms')
plt.ylabel('UHF-Signal / mV')
plt.title('UHF')

x = df.T.to_numpy()[1]
peaks, _ = find_peaks(x, distance = 150, height = 4)
sgf = savgol_filter(peaks, 51, 3)
plt.plot(sgf, x[peaks], c = 'orange')
plt.plot(peaks, x[peaks], 'o', c = 'red')
plt.show()

scipy 黄油过滤器

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from scipy.signal import find_peaks, butter, filtfilt

df = pd.read_csv('signal.csv')
df.plot(grid = 1,
        c = (0,0,255/255),
        linewidth = 0.5,
        figsize = (10,5),
        legend = False,
        xlim = [df.index[0], df.index[-1]],
        ylim = 0)
plt.xlabel('Zeit / ms')
plt.ylabel('UHF-Signal / mV')
plt.title('UHF')

x = df['1'].values
peaks, _ = find_peaks(x, distance = 150, height = 4)
c, e = butter(10, 0.3)
z = filtfilt(c, e, peaks)
plt.plot(z, x[peaks], c = 'orange')
plt.plot(peaks, x[peaks], 'o', c = 'red')
plt.show()

如你所见,结果是一样的。我怎样才能抚平橙色线?我想要这样的东西:

提前致谢

您平滑了错误的变量。 peaksx 的索引(实际上是高度/y 值,这让一切都有些混乱)。替换

sgf = savgol_filter(x[peaks], 5, 3)
plt.plot(peaks, sgf, c = 'orange', linewidth=3)

对于代码中的相应行,会生成以下图:

拟合度不是很好,但您使用的两种方法都不能很好地处理 x=2000 周围的急剧过渡。接下来我会尝试卡尔曼滤波器,或者——如果所有指数的衰减常数都相同——尝试使用非负反卷积将指数直接拟合到数据,如讨论的那样 here