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()
#------------------------------------------------------------------------------
# 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
10
我喜欢剪辑而不是放弃 . 以下内容将在第2和第98位移动到位 .
df_list = list(df)
minPercentile = 0.02
maxPercentile = 0.98
for _ in range(numCols):
df[df_list[_]] = df[df_list[_]].clip((df[df_list[_]].quantile(minPercentile)),(df[df_list[_]].quantile(maxPercentile)))
0
像在 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[~((S-S.mean()).abs() > 3*S.std())]
print '\n'*5, 'All values with decimal 1 are non-outliers. In the other hand, all values with 6 in the decimal are.'
print '\nDef DATA:\n%s\n\nFiltred Values with %s stds:\n%s\n\nOutliers:\n%s' %(df, stds, dfv, dfo)
13 回答
如果你喜欢方法链接,你可以获得所有数字列的布尔条件,如下所示:
每列的每个值将根据其是否小于三个标准差而转换为
True/False
.删除和删除异常值我认为统计上是错误的 . 它使数据与原始数据不同 . 还使数据的形状不均匀,因此最好的方法是通过对数据进行对数转换来减少或避免异常值的影响 . 这对我有用:
另一种选择是转换数据,以减轻异常值的影响 . 您可以通过winsorizing您的数据来做到这一点 .
我放弃异常值的功能
我喜欢剪辑而不是放弃 . 以下内容将在第2和第98位移动到位 .
像在
numpy.array
中一样使用boolean
索引对于一个系列,它是相似的:
scipy.stats
有方法trim1()
和trimboth()
根据排名和引入的删除值百分比将单行中的异常值删除 .由于我处于数据科学之旅的早期阶段,我正在使用下面的代码处理异常值 .
对于每个dataframe列,您可以获得分位数:
然后过滤:
以下是数据和2组的完整示例:
进口:
包含2组的数据示例:G1:第1组.G2:第2组:
将文本数据读取到pandas数据帧:
使用标准偏差定义异常值
定义过滤后的数据值和异常值:
打印结果:
此答案类似于@tanemaki提供的答案,但使用
lambda
表达式而不是scipy stats
.要过滤DataFrame,其中只有一列(例如'B')在三个标准差内:
如果数据框中有多个列,并且想要删除至少有一列中具有异常值的所有行,则以下表达式将一次性执行此操作 .