【问题标题】:Fixing outliers with an user defined function使用用户定义的函数修复异常值
【发布时间】:2020-10-13 22:49:38
【问题描述】:

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

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 新手,尤其是函数。任何帮助,将不胜感激。 提前致谢。

问候, 输入电压

【问题讨论】:

  • 输入 (df) 是 pandas 数据框吗?或者你只是在看 numpy 数组?

标签: python numpy outliers


【解决方案1】:

更改在您的函数之外不可见,因为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)

【讨论】:

    【解决方案2】:

    这是一个命题:

    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)
    

    【讨论】:

    • 你计算平均值和标准两次
    【解决方案3】:

    使用您提供的代码:

    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
    

    【讨论】:

      【解决方案4】:

      如果我没有正确阅读问题,则输入是 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)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-10-29
        • 2016-10-07
        • 1970-01-01
        • 2021-12-16
        • 1970-01-01
        • 2017-03-04
        • 2019-06-20
        • 1970-01-01
        相关资源
        最近更新 更多