java中算术异常值_检测并排除Pandas数据帧中的异常值

回答(13)

e15298c6a3b4591803e154ab0c3b3e2e.png

2 years ago

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

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

每列的每个值将根据其是否小于三个标准差而转换为 True/False .

e15298c6a3b4591803e154ab0c3b3e2e.png

2 years ago

删除和删除异常值我认为统计上是错误的 . 它使数据与原始数据不同 . 还使数据的形状不均匀,因此最好的方法是通过对数据进行对数转换来减少或避免异常值的影响 . 这对我有用:

np.log(data.iloc[:, :])

e15298c6a3b4591803e154ab0c3b3e2e.png

2 years ago

另一种选择是转换数据,以减轻异常值的影响 . 您可以通过winsorizing您的数据来做到这一点 .

import pandas as pd

from scipy.stats import mstats

%matplotlib inline

test_data = pd.Series(range(30))

test_data.plot()

a4b796d0-189b-4d8d-a0fb-a4a7d7eb7de5.png

# 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()

ad9af603-8bb0-4793-8fd9-3779ea9d45b8.png

e15298c6a3b4591803e154ab0c3b3e2e.png

2 years ago

我放弃异常值的功能

def drop_outliers(df, field_name):

distance = 1.5 * (np.percentile(df[field_name], 75) - np.percentile(df[field_name], 25))

df.drop(df[df[field_name] > distance + np.percentile(df[field_name], 75)].index, inplace=True)

df.drop(df[df[field_name] < np.percentile(df[field_name], 25) - distance].index, inplace=True)

e15298c6a3b4591803e154ab0c3b3e2e.png

2 years ago

#------------------------------------------------------------------------------

# 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

e15298c6a3b4591803e154ab0c3b3e2e.png

2 years ago

我喜欢剪辑而不是放弃 . 以下内容将在第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)))

e15298c6a3b4591803e154ab0c3b3e2e.png

2 years ago

像在 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())]

e15298c6a3b4591803e154ab0c3b3e2e.png

2 years ago

scipy.stats 有方法 trim1() 和 trimboth() 根据排名和引入的删除值百分比将单行中的异常值删除 .

e15298c6a3b4591803e154ab0c3b3e2e.png

2 years ago

由于我处于数据科学之旅的早期阶段,我正在使用下面的代码处理异常值 .

#Outlier Treatment

def outlier_detect(df):

for i in df.describe().columns:

Q1=df.describe().at['25%',i]

Q3=df.describe().at['75%',i]

IQR=Q3 - Q1

LTV=Q1 - 1.5 * IQR

UTV=Q3 + 1.5 * IQR

x=np.array(df[i])

p=[]

for j in x:

if j < LTV or j>UTV:

p.append(df[i].median())

else:

p.append(j)

df[i]=p

return df

e15298c6a3b4591803e154ab0c3b3e2e.png

2 years ago

对于每个dataframe列,您可以获得分位数:

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

然后过滤:

df[df["col"] < q]

e15298c6a3b4591803e154ab0c3b3e2e.png

2 years ago

以下是数据和2组的完整示例:

进口:

from StringIO import StringIO

import pandas as pd

#pandas config

pd.set_option('display.max_rows', 20)

包含2组的数据示例:G1:第1组.G2:第2组:

TESTDATA = StringIO("""G1;G2;Value

1;A;1.6

1;A;5.1

1;A;7.1

1;A;8.1

1;B;21.1

1;B;22.1

1;B;24.1

1;B;30.6

2;A;40.6

2;A;51.1

2;A;52.1

2;A;60.6

2;B;80.1

2;B;70.6

2;B;90.6

2;B;85.1

""")

将文本数据读取到pandas数据帧:

df = pd.read_csv(TESTDATA, sep=";")

使用标准偏差定义异常值

stds = 1.0

outliers = df[['G1', 'G2', 'Value']].groupby(['G1','G2']).transform(

lambda group: (group - group.mean()).abs().div(group.std())) > stds

定义过滤后的数据值和异常值:

dfv = df[outliers.Value == False]

dfo = df[outliers.Value == True]

打印结果:

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)

e15298c6a3b4591803e154ab0c3b3e2e.png

2 years ago

此答案类似于@tanemaki提供的答案,但使用 lambda 表达式而不是 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)]

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

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

e15298c6a3b4591803e154ab0c3b3e2e.png

2 years ago

如果数据框中有多个列,并且想要删除至少有一列中具有异常值的所有行,则以下表达式将一次性执行此操作 .

df = pd.DataFrame(np.random.randn(100, 3))

from scipy import stats

df[(np.abs(stats.zscore(df)) < 3).all(axis=1)]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值