平滑离散数据集 - python

我正在尝试使此数据集平滑,并生成一条带有误差线的代表性曲线。粗略地离散了获取数据点的方法。我没有太多编程经验,但是正在尝试学习。我读到高斯滤波器可能是一个不错的选择。任何帮助,将不胜感激。

这是一个示例数据集:

Time (min)  Non-Normalized Shrinkage    Normalized Shrinkage
200 93  1.021978022
202 92  1.010989011
204 92  1.010989011
206 92  1.010989011
208 92  1.010989011
210 92  1.010989011
212 91  1
214 90  0.989010989
216 90  0.989010989
218 90  0.989010989
220 88  0.967032967
222 88  0.967032967
224 87  0.956043956
226 86  0.945054945
228 86  0.945054945
230 86  0.945054945
232 86  0.945054945
234 86  0.945054945
236 85  0.934065934
238 84  0.923076923
240 83  0.912087912
242 83  0.912087912
244 83  0.912087912
246 82  0.901098901
248 83  0.912087912
250 82  0.901098901
252 81  0.89010989
254 81  0.89010989
256 82  0.901098901
258 82  0.901098901
260 79  0.868131868
262 80  0.879120879
264 80  0.879120879

我在网上某个地方找到了此代码段,但我不知道如何实现它,甚至我所寻找的也不知道。

def smoothListGaussian(list,degree=5):  

window=degree*2-1  

weight=numpy.array([1.0]*window)  

weightGauss=[]  

for i in range(window):  

    i=i-degree+1  

    frac=i/float(window)  

    gauss=1/(numpy.exp((4*(frac))**2))  

    weightGauss.append(gauss)  

weight=numpy.array(weightGauss)*weight  

smoothed=[0.0]*(len(list)-window)  

for i in range(len(smoothed)):  

    smoothed[i]=sum(numpy.array(list[i:i+window])*weight)/sum(weight)  

return smoothed 

python大神给出的解决方案

通常,您将为此使用库,而不是自己实现。

我将为此使用scipy.ndimage而不是scipy.signal。如果您有信号处理类,可能会发现scipy.signal方法更直观,但如果没有,则可能会造成混淆。 scipy.ndimage提供了直接的单功能调用gaussian_filter,而不是必须了解其他一些信号处理约定。

这是一个简单的示例,使用您在问题中发布的数据。假设您的数据是定期采样的(即:每2个时间单位)。

import numpy as np
import matplotlib.pyplot as plt
import scipy.ndimage

time, _, shrinkage = np.loadtxt('discrete_data.txt', skiprows=1).T

fig, ax = plt.subplots()
ax.plot(time, shrinkage, 'ro')
ax.plot(time, scipy.ndimage.gaussian_filter(shrinkage, 3))
plt.show()

大部分内容都非常简单明了,但是您可能会注意到我在3中指定的scipy.ndimage.gaussian_filter(shrinkage, 3)的“神奇”值。这就是样本中高斯函数的sigma参数。因为您的数据每2单位被采样一次,所以sigma为6单位。

sigma参数与“钟形曲线”正态分布中的标准偏差完全相似。使其越大,高斯函数将越宽,曲线也将越平滑。通过反复试验,对于该特定数据集,值3似乎是正确的,但是您应该进行实验,看看您认为最合适的是什么。

最后一点:解决此问题的方法有很多。高斯滤波器是一个合理的解决方案,但是还有很多很多其他的问题。如果确切的结果非常重要,则您可能应该比较几种方法,并查看哪种方法最适合您的特定数据集。

在您的评论中,您询问有关将平滑数据保存到文件而不是将其绘制的问题。这是一个可能的解决方法的简单示例:

import numpy as np
import scipy.ndimage

time, _, shrinkage = np.loadtxt('discrete_data.txt', skiprows=1).T
smoothed = scipy.ndimage.gaussian_filter(shrinkage, 3)

np.savetxt('smoothed_data.txt', np.c_[time, smoothed])