时间序列数据的异常值检测

问题描述 投票:0回答:2

我有一个 pandas 数据框,我想在其中检测单个列上的异常值。请记住,我在数据处理/清理方面没有经验。

你可以在下图中看到我确实有一些异常值,最明显的是 08:00:00 标记上方的那个。

我想要的是检测这些异常值,而不是删除它们,我想将它们修改为它之前的 10 个值的平均值(因此第 11 行的值将更改为第 1 行的平均值-10).

我研究过计算 z 分数并以此为基础寻找异常值,但它似乎关注的是总数据集的标准差,而不仅仅是局部范围。您可以在下面看到我为此编写的代码。

def dfCleaning(df):
    df.reset_index(drop=True, inplace=True)
    z = np.abs(stats.zscore(df['MW']))

    for x in np.where((z > 3) | (z < -3)):
        for index in x:
            df.loc[index, 'MW'] = df.iloc[max(0, index-11) : max(1,index-1)]['MW'].mean()

    return df

因此,如果有一种方法可以根据数据集中的一系列行(可能是焦点行上下 50 行)来检测异常值,如果有人能向我解释一下,我将不胜感激。

python pandas dataframe data-cleaning outliers
2个回答
0
投票

这是移除离群值函数的示例。但我建议将您的数据分成多个时间。每天或每周应用删除离群值函数,然后将其连接起来。

def remove_outliers(df_in, col_name):
        q1 = df_in[col_name].quantile(0.25)
        q3 = df_in[col_name].quantile(0.75)
        iqr = q3 -q1
        fence_low  = q1 -1.5 *iqr
        fence_high = q3 +1.5 *iqr
        df_out = df_in.loc[(df_in[col_name] > fence_low) & (df_in[col_name] < fence_high)]
        return df_out

0
投票

您可以使用:

def zscore(s, window, thresh=3, return_all=False):
    roll = s.rolling(window=window, min_periods=1, center=True)
    avg = roll.mean()
    std = roll.std(ddof=0)
    z = s.sub(avg).div(std)   
    m = z.between(-thresh, thresh)
    
    if return_all:
        return z, avg, std, m
    return s.where(m, avg)

df['MW2'] = zscore(df['MW'], window=50)
© www.soinside.com 2019 - 2024. All rights reserved.