我有一个包含随机数量的整数和/或浮点数的列表。我想要实现的是找到我的数字中的异常(希望使用正确的词语来解释这一点)。例如:
list = [1, 3, 2, 14, 108, 2, 1, 8, 97, 1, 4, 3, 5]
我的问题是,这些值可能一直不同。也许常规范围在 1.000 到 1.200 之间,例外情况在 50 万范围内。
有没有函数可以过滤掉这些特殊数字?
假设您的清单是
l
:
如果您知道要过滤某个百分位数/分位数,您可以 用途:
这会删除底部 10% 和顶部 90%。当然,您可以更改其中任何一个 将它们调整为您想要的截止值(例如,您可以删除底部过滤器,只过滤示例中的顶部 90%):
import numpy as np
l = np.array(l)
l = l[(l>np.quantile(l,0.1)) & (l<np.quantile(l,0.9))].tolist()
输出:
[ 3 2 14 2 8 4 3 5]
如果您不确定百分位截止值并希望了解 删除异常值:
您可以通过调整参数
m
来调整异常值的截止值
函数调用。它越大,去除的异常值就越少。与其他异常值去除技术相比,该函数似乎对各种类型的异常值更加稳健。
import numpy as np
l = np.array(l)
def reject_outliers(data, m=6.):
d = np.abs(data - np.median(data))
mdev = np.median(d)
s = d / (mdev if mdev else 1.)
return data[s < m].tolist()
print(reject_outliers(l))
输出:
[1, 3, 2, 14, 2, 1, 8, 1, 4, 3, 5]
在您的案例中查找异常值的另一种方法是消除 Q1 和 Q3 之外超过 1.5xIQR 的值。 (1.5 是一个可接受的值,但您当然可以调整它)。
Q 是低于数据中值 (Q1) 或高于中值 (Q3) 的数据的中值,例如:
23 - 24 - 29 - 33 - 38 - 41 - 42 - 50 - 56 - 60 - 62
Median
Q1 Q3
IQR 是四分位距(简单来说:Q3-Q1)
你不需要 numpy 来计算这个:
from statistics import median, StatisticsError
l = [1, 3, 2, 14, 108, 2, 1, 8, 97, 1, 4, 3, 5]
m = median(l)
try:
q1 = median([_ for _ in l if _ < m])
except StatisticsError:
# No values below median. Can be the case if there are many equal values and only a few above it
q1 = m
try:
q3 = median([_ for _ in l if _ > m])
except StatisticsError:
# No values above median. Can be the case if there are many equal values and only a few below it
q3 = m
iqr = q3 - q1
outliers = [_ for _ in l if _ > q3 + (iqr * 1.5) or _ < q1 - (iqr * 1.5)]
print(outliers)
>>> [108, 97]
您可以使用内置的
filter()
方法:
lst1 = [1, 3, 2, 14, 108, 2, 1, 8, 97, 1, 4, 3, 5]
lst2 = list(filter(lambda x: x > 5,lst1))
print(lst2)
输出:
[14, 108, 8, 97]
所以这里有一个方法来阻止那些偏差者
import math
_list = [1, 3, 2, 14, 108, 2, 1, 8, 97, 1, 4, 3, 5]
def consts(_list):
mu = 0
for i in _list:
mu += i
mu = mu/len(_list)
sigma = 0
for i in _list:
sigma += math.pow(i-mu,2)
sigma = math.sqrt(sigma/len(_list))
return sigma, mu
def frequence(x, sigma, mu):
return (1/(sigma*math.sqrt(2*math.pi)))*math.exp(-(1/2)*math.pow(((x-mu)/sigma),2))
sigma, mu = consts(_list)
new_list = []
for i in range(len(_list)):
if frequence(_list[i], sigma, mu) > 0.01:
new_list.append(i)
print(new_list)