簡體   English   中英

在 Python 中用 nan 查找和替換異常值

[英]Find and replace outliers with nan in Python

我開始使用python,我試圖使用分位數每年查找異常值,我的數據組織如下:年份的列,並且每年我都有幾個月及其相應的鹽度和溫度

year=[1997:2021]
month=[1,2...]
SAL=[33,32,50,......,35,...]

以下是我的代碼:

#1st quartile
Q1 = DF['SAL'].quantile(0.25)
#3rd quartile
Q3 = DF['SAL'].quantile(0.75)
#calculate IQR
IQR = Q3 - Q1
print(IQR)
df_out = DF['SAL'][((DF['SAL'] < (Q1 - 1.5 * IQR)) |(DF['SAL'] > (Q3 + 1.5 * IQR)))]

我想識別異常值的月份和年份並將其替換為 nan。

要獲得每年的異常值,您需要通過groupby計算每年的四分位數。 除此之外,您的代碼沒有太大變化,但我最近了解到這between似乎很有用:

import numpy as np

clean_data = list()

for year, group in DF.groupby('year'):
    
    Q1 = group['SAL'].quantile(0.25)
    Q3 = group['SAL'].quantile(0.75)
    IQR = Q3 - Q1
    
    # set all values to np.nan that are not (~) in between the two values
    group.loc[~group['SAL'].between(Q1 - 1.5 * IQR, 
                                Q3 + 1.5 * IQR, 
                                inclusive=False),
              'SAL'] = np.nan
    
    clean_data.append(group)

clean_df = pd.concat(clean_data)

您可以使用以下功能。 它使用低於 Q1-1.5IQR 或高於 Q3+1.5IQR 的異常值的定義,例如經典的箱線圖。

import pandas as pd
import numpy as np

df = pd.DataFrame({'year':  np.repeat(range(1997,2022), 12),
                   'month': np.tile(range(12), 25)+1,
                   'SAL':   np.random.randint(20,40, size=12*25)+np.random.choice([0,-20, 20], size=12*25, p=[0.9,0.05,0.05]),
                  })

def outliers(s, replace=np.nan):
    Q1, Q3 = np.percentile(s, [25 ,75])
    IQR = Q3-Q1
    return s.where((s > (Q1 - 1.5 * IQR)) & (s < (Q3 + 1.5 * IQR)), replace)

# add new column with excluded outliers
df['SAL_excl'] = df.groupby('year')['SAL'].apply(outliers)

檢查它是否有效:

有異常值:

import seaborn as sns
sns.boxplot(data=df, x='year', y='SAL')

帶有異常值的箱線圖

沒有異常值:

sns.boxplot(data=df, x='year', y='SAL_excl')

沒有異常值的箱線圖

注意。 由於過濾,數據現在有新的 Q1/Q3/IQR,因此可能會出現新的異常值。

如何檢索具有異常值的行:

df[df['SAL_excl'].isna()]

輸出:

     year  month  SAL  SAL_excl
28   1999      5   53       NaN
33   1999     10    7       NaN
94   2004     11   52       NaN
100  2005      5   38       NaN
163  2010      8    6       NaN
182  2012      3   25       NaN
188  2012      9   22       NaN
278  2020      3   53       NaN
294  2021      7    9       NaN

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM