matlab中默认生成一个2 * k + 1大小的窗口,不足的部分使用目前的数据填充。
使用正态分布标准偏差估计值(值为1.4826) * 绝对中位差,得到一个估计标准差。
matlab中默认为3个估计标准差以外的就判定为离群点。
代码如下:
def hampel(X):
length = X.shape[0] - 1
k = 3
nsigma = 3
iLo = np.array([i - k for i in range(0, length + 1)])
iHi = np.array([i + k for i in range(0, length + 1)])
iLo[iLo < 0] = 0
iHi[iHi > length] = length
xmad = []
xmedian = []
for i in range(length + 1):
w = X[iLo[i]:iHi[i] + 1]
medj = np.median(w)
mad = np.median(np.abs(w - medj))
xmad.append(mad)
xmedian.append(medj)
xmad = np.array(xmad)
xmedian = np.array(xmedian)
scale = 1.4826 # 缩放
xsigma = scale * xmad
xi = ~(np.abs(X - xmedian) <= nsigma * xsigma) # 找出离群点(即超过nsigma个标准差)
# 将离群点替换为中为数值
xf = X.copy()
xf[xi] = xmedian[xi]
return xf
X = np.array([1, 2, 3, 4, 100, 4, 3, 2, 1])
res = hampel(X)
plt.plot(X)
plt.plot(res, '--')
plt.show()
结果图如下:
离群点已经被纠正,可以通过修改窗口大小调整为自己合适的值。