【问题标题】:How can i replace outliers with the mean of previous and next neighbour?如何用前一个和下一个邻居的平均值替换异常值?
【发布时间】:2019-10-07 16:20:59
【问题描述】:

我有一个非常大的数据集,它来自拍打两个激光频率并读出带有频率的拍频。柜台。

问题是我的数据集中有很多异常值。

过滤不是一种选择,因为过滤/去除异常值会杀死我用来分析我的拍频的艾伦偏差的宝贵信息。

去除异常值的问题是我想比较三个不同拍频的艾伦偏差。如果我现在删除一些点,我的 x 轴将比以前更短,并且我的艾伦偏差 x 轴将缩放不同。 (adev 基本上建立了一个新的 x 轴,从我的采样率到最长测量时间的间隔开始 -> 这是我的最高拍频 x 轴值。)

对不起,如果这令人困惑,我想提供尽可能多的信息。

无论如何,到目前为止,我所做的是让我的整个艾伦偏差正常工作并成功删除异常值,将我的列表分成区间并将每个区间的所有 y 值与区间的标准差进行比较。

我现在想要改变的是,我不想删除异常值,而是用它们的前一个和下一个邻居的平均值替换它们。

您可以在下面找到我的异常值列表的测试代码,使用 numpy where 似乎有问题,我真的不明白为什么。

错误是“'numpy.int32'对象没有属性'where'”。我必须将我的数据集转换为熊猫结构吗?

代码所做的是搜索高于/低于我的阈值的值,用 NaN 替换它们,然后用我的平均值替换 NaN。我不太喜欢使用 NaN 替换,因此我将非常感谢您的帮助。


l = np.array([[0,4],[1,3],[2,25],[3,4],[4,28],[5,4],[6,3],[7,4],[8,4]])

print(*l)

sd = np.std(l[:,1])

print(sd)

for i in l[:,1]:

    if l[i,1] > sd:
        print(l[i,1])
        l[i,1].where(l[i,1].replace(to_replace = l[i,1], value = np.nan),
                other = (l[i,1].fillna(method='ffill')+l[i,1].fillna(method='bfill'))/2)

所以我想要的是将异常值替换为前一个/后一个邻居的方法的列表/数组

错误消息:“numpy.int32”对象没有属性“where”

【问题讨论】:

    标签: python python-3.x numpy jupyter


    【解决方案1】:

    一个选项确实是把所有的工作都转化为 pandas 只是用

    import pandas as pd
    dataset = pd.DataFrame({'Column1':data[:,0],'Column2':data[:,1]})
    

    这将解决错误,因为 pandas 数据框对象具有 where 命令。 但是,这不是强制性的,我们仍然可以只使用 numpy 进行操作

    例如,检测异常值的最简单方法是查看它们是否不在均值+-3std 范围内。 下面的代码示例,使用您的设置

    import numpy as np
    l = np.array([[0,4],[1,3],[2,25],[3,4],[4,28],[5,4],[6,3],[7,4],[8,4]])
    std = np.std(l[:,1])
    mean=np.mean(l[:,1])
    for i in range (len(l[:,1])):
        if((l[i,1]<=mean+2*std)&(l[i,1]>=mean-2*std)):
            pass
        else:
            if (i!=len(l[:,1])-1)&(i!=0):
                  l[i,1]=(l[i-1,1]+l[i+1,1])/2
            else:
                  l[i,1]=mean
    

    我们在这里首先检查的是行的值是否异常

    if((l[i,1]<=mean+2*std)&(l[i,1]>=mean-2*std)):
            pass
    

    然后检查它是不是第一个或最后一个元素

    if (i!=len(l[:,1])-1)&(i!=1):
    

    如果是的话,就给这个字段加上平均值:

    else:
         l[i,1]=mean     
    

    【讨论】:

    • 嗨,伊戈尔,感谢您的快速回复!如果我是对的,这段代码只是用我的间隔的平均值替换异常值,这对于一个非常小的间隔是可以的,但不是我希望作为最佳解决方案的。有没有一种简单的方法可以用两个相邻点值的平均值替换异常值?类似([i-1]+[i+1])/2
    • 你好,这正是代码现在所做的,如果元素不是数组中的第一个或最后一个元素,我们有 l[i,1]=(l[i-1,1]+ l [i + 1,1])/ 2,但如果它的第一个或最后一个附近没有两个点,所以我只是用所有集合的平均值替换它,但这仅适用于2个值,所有其他值都将被替换两个邻居的平均值
    • 更正了语法错误,现在你可以尝试启动它而无需编辑,注意:2std 是 95% 置信区间,3std 99% 和 1st 大约 66%,在你的小设置中 28 不是异常值对于 99 confidene 间隔,所以我将其更改为 95
    • 啊现在我明白了,我马上试试。将其提取到列表中的最简单方法是什么?我应该将它附加到一个新的空列表中,还是我也可以直接用您的示例给出的 if 循环参数“替换”我的异常值?
    • @SBoles 在检查它们不在 (l[i,1]=mean 之后,它们已经在循环中被替换-2*std) 这意味着它们很可能是异常值
    猜你喜欢
    • 2019-03-14
    • 2014-09-04
    • 2023-03-23
    • 2016-10-03
    • 1970-01-01
    • 2021-12-10
    • 1970-01-01
    • 2020-05-15
    • 2021-12-26
    相关资源
    最近更新 更多