使用用户定义的函数修复异常值

Fixing outliers with an user defined function

我正在尝试编写一个函数来修复数据集中的异常值。即,如果异常值高于上限,则该值将替换为上限,如果该值小于下限,则将替换为下限。下面列出了我创建的函数。

def fix_outliers(df):
    anomalies = []
    df_std = np.std(df)
    df_mean = np.mean(df)
    anomaly_cut_off = df_std * 3
    lower_limit  = df_mean - anomaly_cut_off 
    upper_limit = df_mean + anomaly_cut_off
    df=np.where(df > upper_limit, upper_limit, df)
    df=np.where(df < lower_limit, lower_limit, df)

函数内部发生的变化在我的数据集中没有发生变化。 我是 python 的新手,尤其是函数方面的新手。任何帮助,将不胜感激。 提前致谢。

此致, 文

如果我没看错问题,输入是 pandas 数据框。如果是这种情况,这里有一个解决方案:

NUM_STD = 3 # not strictly needed. Defines what's an outlier. 

def outliers(df):
    df[df > (df.std() * NUM_STD + df.mean())] = list(df.std() * NUM_STD + df.mean())
    df[df < (df.mean() - df.std() * NUM_STD)] = list(df.mean() - df.std() * NUM_STD)
    return df

# for demo purposes - create a dataframe and run outliers. 
normal_dist = lambda : np.random.normal(loc = 100, scale = 50, size = 100)
df = pd.DataFrame({"a" : normal_dist(), "b": normal_dist()})
outliers(df)

更改在函数外部不可见,因为 np.where 创建了一个 new 数组。 Python 中的变量表现得像指向对象的标签(有点类似于 C 指针)。因此操作:

df = <something>

将更新标签 df,但它 不会 更改 df 指向的对象。

正确的更新应该是这样的:

df[df > upper_limit] = upper_limit
df[df < lower_limit] = lower_limit

顺便说一句。有专用于此任务的 numpy 函数。是np.clip。 该操作可以压缩为:

np.clip(df, lower_limit, upper_limit, out=df)

最终函数为:

def fix_outliers(df):
    df_std = np.std(df)
    df_mean = np.mean(df)
    anomaly_cut_off = df_std * 3
    lower_limit  = df_mean - anomaly_cut_off 
    upper_limit = df_mean + anomaly_cut_off
    np.clip(df, lower_limit, upper_limit, out=df)

这里有一个命题:

def fix_outliers(df):

    df_fx=df.copy()
    df_fx_mean=np.nanmean(df_fx)
    df_fx_std=np.nanstd(df_fx)

    upper_limit=df_fx_mean+3*df_fx_std
    lower_limit=df_fx_mean-3*df_fx_std

    df_fx[df_fx>upper_limit]=upper_limit
    df_fx[df_fx<lower_limit]=lower_limit

    return df_fx

df_fixed=fix_outliers(df)

我认为最好创建数据帧的副本然后修改它而不是丢失原始数据。如果你还是只想修改 df:

def fix_outliers(df):
    
    df_mean=np.nanmean(df)
    df_std=np.nanstd(df)

    upper_limit=df_mean+3*df_std
    lower_limit=df_mean-3*df_std

    df[df>upper_limit]=upper_limit
    df[df<lower_limit]=lower_limit
   

fix_outliers(df)

使用您提供的代码:

def fix_outliers(df):
    df_std = np.std(df)
    df_mean = np.mean(df)
    anomaly_cut_off = df_std * 3
    lower_limit  = df_mean - anomaly_cut_off 
    upper_limit = df_mean + anomaly_cut_off

    for col in df.columns:
        for i in range(df.shape[0]):
            if df[col][i] > upper_limit[col]:
                df[col][i] = upper_limit[col]
            elif df[col][i] < lower_limit[col]:
                df[col][i] = lower_limit[col]

    return df