【问题标题】:Algorithm for detecting corrupted data?检测损坏数据的算法?
【发布时间】:2015-08-29 08:00:14
【问题描述】:

我不确定这是否适合提问,如果这听起来无关紧要,请原谅我。这是我的情况:

我的数据集及时为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 用于此?

如果我要从头开始实现一个方法,我会受伤:

  1. 从附近的数据点计算增量
  2. 为检测损坏的数据选择一个合适的阈值

但我不确定这是否足够好,也许我忽略了其他部分,这会导致大量误报。

另外,我正在使用PythonPandas 来处理数据,所以相关资源会很棒。

【问题讨论】:

    标签: python algorithm pandas


    【解决方案1】:

    检测损坏数据或异常值的一种方法是首先计算序列的滚动中位数(它对异常值具有鲁棒性),然后计算实际观察值与滚动中位数之间的距离。过滤掉距离大于阈值的那些观测值。

    # 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
    

    【讨论】:

      【解决方案2】:

      您还可以识别 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,它也适用于一维数组,并返回一个标量,将函数应用于由足迹定义的移动窗口。这是一个关于如何仅在 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 列]

      您也可以将这两个函数合并在一起,但为了质量分析,我不会并且总是保留原始数据、有效数据和插值数据。

      【讨论】:

        猜你喜欢
        • 2011-08-20
        • 1970-01-01
        • 2011-09-16
        • 2010-09-25
        • 2012-04-13
        • 2011-07-24
        • 1970-01-01
        • 1970-01-01
        • 2010-10-11
        相关资源
        最近更新 更多