如何在不考虑每个单独值的情况下,使用平滑,连续的线绘制以下噪声数据?我只想以更好的方式展示行为,而不关心嘈杂和极端的价值观。这是我正在使用的代码:
import numpy
import sys
import matplotlib.pyplot as plt
from scipy.interpolate import spline
dataset = numpy.genfromtxt(fname='data', delimiter=",")
dic = {}
for d in dataset:
dic[d[0]] = d[1]
plt.plot(range(len(dic)), dic.values(),linestyle='-', linewidth=2)
plt.savefig('plot.png')
plt.show()
答案 0 :(得分:5)
在previous answer中,我被介绍到Savitzky Golay filter,这是一种特殊类型的低通滤波器,非常适合数据平滑。您希望得到的曲线“平滑”是一个偏好的问题,这可以通过窗口大小和插值多项式的顺序来调整。使用sg_filter
的食谱示例:
import numpy as np
import sg_filter
import matplotlib.pyplot as plt
# Generate some sample data similar to your post
X = np.arange(1,1000,1)
Y = np.log(X**3) + 10*np.random.random(X.shape)
Y2 = sg_filter.savitzky_golay(Y, 101, 3)
plt.plot(X,Y,linestyle='-', linewidth=2,alpha=.5)
plt.plot(X,Y2,color='r')
plt.show()
答案 1 :(得分:0)
有不止一种方法可以做到!
这里我展示了如何使用各种技术来降低噪音:
坚持@Hooked 示例数据以保持一致性:
import numpy as np
import matplotlib.pyplot as plt
X = np.arange(1, 1000, 1)
Y = np.log(X ** 3) + 10 * np.random.random(X.shape)
plt.plot(X, Y, alpha = .5)
plt.show()
有时您只需要一个 moving average。
例如,使用窗口大小为 100 的 pandas:
import pandas as pd
df = pd.DataFrame(Y, X)
df_mva = df.rolling(100).mean() # moving average with a window size of 100
df_mva.plot(legend = False);
您可能需要对数据尝试多种窗口大小。请注意,df_mva
的前 100 个值将为 NaN,但可以使用 dropna
方法删除这些值。
pandas rolling function 的使用详情。
我已成功使用 LOWESS(局部加权散点图平滑)从重复测量数据集中去除噪声。有关局部回归方法的更多信息,包括 LOWESS 和 LOESS,here。这是一种只需调整一个参数的简单方法,根据我的经验,该方法可提供良好的结果。
以下是如何使用 statsmodels 实现应用 LOWESS 技术:
import statsmodels.api as sm
y_lowess = sm.nonparametric.lowess(Y, X, frac = 0.3) # 30 % lowess smoothing
plt.plot(y_lowess[:, 0], y_lowess[:, 1]) # some noise removed
plt.show()
可能需要改变 frac
参数,它是估计每个 y 值时使用的数据的分数。增加 frac
值以增加平滑量。 frac
值必须介于 0 和 1 之间。
有关 statsmodels lowess usage 的更多详细信息。
Scipy 提供了一组可能合适的 low pass filters。
应用过滤器后:
from scipy.signal import lfilter
n = 50 # larger n gives smoother curves
b = [1.0 / n] * n # numerator coefficients
a = 1 # denominator coefficient
y_lf = lfilter(b, a, Y)
plt.plot(X, y_lf)
plt.show()
检查 scipy lfilter documentation 以了解有关如何在差分方程中使用分子和分母系数的实现细节。
scipy.signal package 中还有其他过滤器。
最后,这是一个 radial basis function interpolation 的例子:
from scipy.interpolate import Rbf
rbf = Rbf(X, Y, function = 'multiquadric', smooth = 500)
y_rbf = rbf(X)
plt.plot(X, y_rbf)
plt.show()
通过增加 smooth
参数可以实现更平滑的近似。要考虑的替代 function
参数包括“cubic”和“thin_plate”。在考虑 function
值时,我通常先尝试 'thin_plate',然后是 'cubic';然而,'thin_plate' 和 'cubic' 似乎都在与这个数据集中的噪声作斗争。
检查 scipy docs 中的其他 Rbf
选项。 Scipy 提供了其他单变量和多变量插值技术(请参阅此 tutorial)。