检测并排除Pandas数据框中的exception值

我有一个只有几列的pandas数据框。

现在我知道某些行是基于某个列值的exception值。

例如列 – “Vol”具有12.xx左右的所有值和4000的值

现在我想排除那些有这样的卷列的行。

所以基本上我需要把一个filter,以便我们select所有行中的某一列的值是在平均值的3个标准偏差内。

什么是一个优雅的方式来实现这一目标。

像在numpy.array一样使用boolean索引

 df=pd.DataFrame({'Data':np.random.normal(size=200)}) #example dataset of normally distributed data. df[np.abs(df.Data-df.Data.mean())<=(3*df.Data.std())] #keep only the ones that are within +3 to -3 standard deviations in the column 'Data'. df[~(np.abs(df.Data-df.Data.mean())>(3*df.Data.std()))] #or if you prefer the other way around 

对于一个系列是类似的:

 S=pd.Series(np.random.normal(size=200)) S[~((SS.mean()).abs()>3*S.std())] 

如果数据框中有多个列,并且希望删除至less一列中具有exception值的所有行,则下面的expression式可以一次性完成。

 df = pd.DataFrame(np.random.randn(100, 3)) from scipy import stats df[(np.abs(stats.zscore(df)) < 3).all(axis=1)] 

对于每个dataframe列,您可以通过以下方式获得分位数:

 q = df["col"].quantile(0.99) 

然后过滤:

 df[df["col"] < q] 

这个答案类似于@tanemaki提供的答案,但是使用lambdaexpression式而不是scipy stats

 df = pd.DataFrame(np.random.randn(100, 3), columns=list('ABC')) df[df.apply(lambda x: np.abs(x - x.mean()) / x.std() < 3).all(axis=1)] 

要过滤只有一列(例如'B')在三个标准偏差内的DataFrame:

 df[((df.B - df.B.mean()) / df.B.std()).abs() < 3] 

scipy.stats有方法scipy.stats trim1()trimboth()根据排名和已删除值的介绍百分比,在一行中删除exception值。

另一个select是转换您的数据,以减lessexception值的影响。 你可以通过winsorizing你的数据来做到这一点。

 import pandas as pd from scipy.stats import mstats %matplotlib inline test_data = pd.Series(range(30)) test_data.plot() 

原始数据

 # Truncate values to the 5th and 95th percentiles transformed_test_data = pd.Series(mstats.winsorize(test_data, limits=[0.05, 0.05])) transformed_test_data.plot() 

Winsorized数据

 #------------------------------------------------------------------------------ # accept a dataframe, remove outliers, return cleaned data in a new dataframe # see http://www.itl.nist.gov/div898/handbook/prc/section1/prc16.htm #------------------------------------------------------------------------------ def remove_outlier(df_in, col_name): q1 = df_in[col_name].quantile(0.25) q3 = df_in[col_name].quantile(0.75) iqr = q3-q1 #Interquartile range 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 

如果你喜欢方法链接,你可以像这样获得所有数字列的布尔条件:

 df.sub(df.mean()).div(df.std()).abs().lt(3) 

每列的每个值将被转换为True/False基于它是否小于三个标准偏差的意思或不。