我不确定这是否是正确的地方,所以请原谅我,如果这个声音不相关的话。这是我的情况:
我的数据集及时为continual
,我需要处理一些errones data
。与邻居相比,它们的价值突然增加。
这是数据集的一部分。如您所见,第4个值(28.3
)突然增加。 (值在最后一栏)
19741212,0700,200,1,N, 4.6
19741212,0800,190,1,N, 4.6
19741212,0900,180,1,N, 5.7
19741212,1000,160,1,N, 28.3 # wrong data, need interpolate from neighbors
19741212,1100,170,1,N, 4.6
19741212,1200,200,1,N, 5.1
19741212,1300,230,1,N, 5.1
我需要identify
他们,然后从附近的数据中interpolate
替换它们。我想知道现有algorithm
是否存在?
如果我从头开始实施一种方法,我就会伤害:
但是我不确定这是否足够好,也许我忽略了其他部分,这会导致大量的误报。
另外,我使用Python
和Pandas
来处理数据,因此相关资源会很棒。
答案 0 :(得分:2)
检测损坏数据或异常值的一种方法是首先计算一系列的滚动中位数(它对异常值的鲁棒性),然后计算实际观测值与滚动中位数之间的距离。过滤掉距离大于阈值的观察结果。
# your data
# ====================================
print(df)
A B C D E
19741212 700 200 1 N 4.6
19741212 800 190 1 N 4.6
19741212 900 180 1 N 5.7
19741212 1000 160 1 N 28.3
19741212 1100 170 1 N 4.6
19741212 1200 200 1 N 5.1
19741212 1300 230 1 N 5.1
# roling median, 3-term moving windows
# =================================================
res = pd.rolling_median(df['E'], window=3, center=True)
print(res)
19741212 NaN
19741212 4.6
19741212 5.7
19741212 5.7
19741212 5.1
19741212 5.1
19741212 NaN
dtype: float64
# threshold 20% from rolling median
threshold = 0.2
mask = abs(df['E'] - res)/res > threshold
# replace outliers with rolling medians
df.loc[mask, 'E'] = res[mask]
print(df)
A B C D E
19741212 700 200 1 N 4.6
19741212 800 190 1 N 4.6
19741212 900 180 1 N 5.7
19741212 1000 160 1 N 5.7
19741212 1100 170 1 N 4.6
19741212 1200 200 1 N 5.1
19741212 1300 230 1 N 5.1
答案 1 :(得分:1)
您还可以识别ouliers,您可以测试它们与平均值的距离并设置标准差阈值。
根据https://stackoverflow.com/a/11686764/2477491,您可以使用以下内容将异常值设置为NaN:
def reject_outliers(data, m=2): # 2 is the std treshold, fit for your needs.
return data[abs(data - np.mean(data)) < m * np.std(data)]
data[6] = reject_outliers(data[5]) # creates a new column with outliers set to Nan
0 1 2 3 4 5 6
0 19741212 700 200 1 N 4.6 4.6
1 19741212 800 190 1 N 4.6 4.6
2 19741212 900 180 1 N 5.7 5.7
3 19741212 1000 160 1 N 28.3 NaN
4 19741212 1100 170 1 N 4.6 4.6
5 19741212 1200 200 1 N 5.1 5.1
6 19741212 1300 230 1 N 5.1 5.1
如果你的系列有趋势,你可能宁愿将它应用于时间移动窗口而不是整个系列。
关于在窗口上应用自定义函数,我通常使用scipy.ndimage.filters.generic_filter
也可以使用1d数组,并返回在脚印定义的移动窗口上应用函数的标量。下面是一个关于如何仅在1x3足迹中插入NaN的平均值的示例:
from scipy import ndimage as im
def interpNan(win): # with win the 1x3 window
if win[1] != win[1]: # if center of footprint is a nan
return round(np.nanmean(win), 1)
else:
return round(win[1], 1)
footprint = np.array([1,1,1])
data[7] = im.generic_filter(data[6], interpNan, footprint = footprint )
0 1 2 3 4 5 6 7
0 19741212 700 200 1 N 4.6 4.6 4.6
1 19741212 800 190 1 N 4.6 4.6 4.6
2 19741212 900 180 1 N 5.7 5.7 5.7
3 19741212 1000 160 1 N 28.3 NaN 5.2
4 19741212 1100 170 1 N 4.6 4.6 4.6
5 19741212 1200 200 1 N 5.1 5.1 5.1
6 19741212 1300 230 1 N 5.1 5.1 5.1
[7行x 8列]
您还可以合并这两个函数,但是对于质量分析,我并不总是保留原始数据,有效数据和插值数据。