先介绍使用到的方法原理,也就是一种异常检测的方法。 
首先要先了解箱线图。

箱线图

箱线图(Boxplot)也称箱须图(Box-whisker Plot),是利用数据中的五个统计量:最小值、第一四分位数、中位数、第三四分位数与最大值来描述数据的一种方法,它也可以粗略地看出数据是否具有有对称性,分布的分散程度等信息,特别可以用于对几个样本的比较。 ——MBAlib 箱线图

先看一下什么是箱线图,下面这个是常见的箱线图样子。

python箱线图异常值过大 箱线图处理异常值_数据

具体含义如下,首先计算出第一四分位数(Q1)、中位数、第三四分位数(Q3)。 
中位数我们都知道,就是将一组数字按从小到大的顺序排序后,处于中间位置(也就是50%位置)的数字。 
同理,第一四分位数、第三四分位数是按从小到大的顺序排序后,处于25%、75%的数字。

令 IQR=Q3−Q1IQR=Q3−Q1 ,那么 Q3+1.5(IQR)Q3+1.5(IQR) 和 Q1−1.5(IQR)Q1−1.5(IQR) 之间的值就是可接受范围内的数值,这两个值之外的数认为是异常值。

在Q3+1.5IQR(四分位距)和Q1-1.5IQR处画两条与中位线一样的线段,这两条线段为异常值截断点,称其为内限;在Q3+3IQR和Q1-3IQR处画两条线段,称其为外限。 
处于内限以外位置的点表示的数据都是异常值,其中在内限与外限之间的异常值为温和的异常值(mild outliers),在外限以外的为极端的异常值(li)的异常值extreme outliers。这种异常值的检测方法叫做Tukey’s method

从矩形盒两端边向外各画一条线段直到不是异常值的最远点 表示该批数据正常值的分布区间点,示该批数据正常值的分布区间。 
一般用“〇”标出温和的异常值,用“*”标出极端的异常值。

python箱线图异常值过大 箱线图处理异常值_异常检测_02

python 代码分享

这段检测异常值的代码是从kaggle上看到的,很简单也很有用。 
代码原地址:https://www.kaggle.com/yassineghouzam/titanic-top-4-with-ensemble-modeling/notebook

通过上面对箱线图的介绍,相信同时也清楚了异常值检测的方法。 
假设我们现在已经有了一份pandas.DataFrame读取后的数据df,其中需要进行检测的列保存在features列表中,每个样本能忍受的最大异常值数量为n。

# Outlier detection 
import pandas as pd
import numpy as np
from collections import Counter

def detect_outliers(df,n,features):

    outlier_indices = []

    # iterate over features(columns)
    for col in features:
        # 1st quartile (25%)
        Q1 = np.percentile(df[col], 25)
        # 3rd quartile (75%)
        Q3 = np.percentile(df[col],75)
        # Interquartile range (IQR)
        IQR = Q3 - Q1

        # outlier step
        outlier_step = 1.5 * IQR

        # Determine a list of indices of outliers for feature col
        outlier_list_col = df[(df[col] < Q1 - outlier_step) | (df[col] > Q3 + outlier_step )].index

        # append the found outlier indices for col to the list of outlier indices 
        outlier_indices.extend(outlier_list_col)

    # select observations containing more than 2 outliers
    outlier_indices = Counter(outlier_indices)        
    multiple_outliers = list( k for k, v in outlier_indices.items() if v > n )

    return multiple_outliers
# detect outliers from "Col1","Col2","Col3","Col4"
df = pd.read_csv("data.csv")
Outliers_to_drop = detect_outliers(df,2,["Col1","Col2","Col3","Col4"])
# Drop outliers
df = df.drop(Outliers_to_drop, axis = 0).reset_index(drop=True)