Python:从列表中删除异常值。什么';这个密码怎么了?

Python:从列表中删除异常值。什么';这个密码怎么了?,python,Python,下面的代码片段来自我的一个函数,它传递了一个数字列表,应该从列表中删除异常值(即非常大或非常小的数字) 正如输出确认的那样,代码似乎没有按预期工作: EXTREMA_CUTOFF_THRESHOLD=3.0 if list_values: avg_val = sum(list_values)/float(len(list_values)) print 'DEBUG: BEFORE:', min(list_values), max(list_values), avg_va

下面的代码片段来自我的一个函数,它传递了一个数字列表,应该从列表中删除异常值(即非常大或非常小的数字)

正如输出确认的那样,代码似乎没有按预期工作:

EXTREMA_CUTOFF_THRESHOLD=3.0

if list_values:    
    avg_val = sum(list_values)/float(len(list_values))
    print 'DEBUG: BEFORE:', min(list_values), max(list_values), avg_val
    list_values = [x for x in list_values if math.fabs(x - avg_val)/float(avg_val) < EXTREMA_CUTOFF_THRESHOLD]

    list_values_len = len(list_values)
    if (list_values_len > 0) and (min_sample_size > 0) and (list_values_len < min_sample_size):
        print 'DEBUG: Insufficient data for stats calculation for row'
    elif (list_values_len > 0):
        print 'DEBUG: AFTER:', min(list_values), max(list_values), avg_val

为什么没有过滤掉极值?

一件事:过滤列表后,您不会重新计算
avg\u val

另一件事:你玩过你的
极限值吗?也许3.0不会从测试数据集中过滤任何内容,但是一个较低的值会


一般评论:在本例中,我将使用
numpy
,并利用数据集的标准偏差(
numpy.std(dataarray)
)来确定异常值(具体方法请参见@mgilson的评论)。关于异常值检测的一个很好的资源似乎是这篇维基百科文章:

请注意,通过
sum/len
计算平均值的简单方法会失去数值精度。此外,您可能还需要计算标准偏差

你的阈值方程

math.fabs(x - avg_val)/float(avg_val) < EXTREMA_CUTOFF_THRESHOLD
math.fabs(x-avg_val)/float(avg_val)
应该是这样的

math.fabs(x - avg_val)/float(   standard_deviation  ) < EXTREMA_CUTOFF_THRESHOLD
math.fabs(x-平均值)/float(标准偏差)
至少如果您计划使用经典的正态分布假设(如3西格玛异常值),这些假设是根据标准偏差定义的

您使用什么阈值?在第一个数据集上,如果您使用的是
3
,很容易看到没有任何值大于455.58904109600002或小于-227.79452054800001

(请注意,使用标准偏差进行标准化应该可以解决这一问题。不要盲目地降低阈值。)


您还计算了错误的长度:
list\u values\u len=len(bid\u values)
您的代码正在工作。只是没有一个极值与平均值的距离超过平均值的3倍,这就是你的算法所暗示的。fabs(x-avg_val)/float(avg_val)
意味着“一个基准到平均值的距离相对于平均值”。我认为这没有多大意义。想象一组出生年份,我。E数字都在1920到2010之间。把距离与平均值的绝对值联系起来没有多大意义


回到正方形:考虑一个更合适的规则来找出要删除的元素。这里的其他答案已经提到了。

您能给我们举一个脚本不希望脚本执行的
列表值的例子吗?对于
列表值=[1,1,1,1,100000000]
它删除了“异常值”。(113-11)/113<3。(302-113) / 113 < 3. 你的门槛不好。(注:对于阈值>1的情况,小值始终保持不变。+1用于添加关于标准偏差的注释。我实际上正在与scipy合作计算样本的统计数据。但是,异常值导致打印最小值和最大值的“无意义”值。就numpy而言,您可以这样做:
x=arr[(x>(3*std-mean))&(X值是价格。因此,与平均值的百分比偏差应该是一个足够好的规则,可以从列表中删除错误的价格。感谢您指出。这是一个打字错误。我已更正了变量名称。现在尝试使用标准偏差!我使用了修剪平均值,并更改了阈值。事实证明…:/Do no不要仅仅改变阈值。问题是你使用了错误的公式。你应该除以标准偏差(而不是平均值!),正如这里的各种答案所解释的那样。
math.fabs(x - avg_val)/float(   standard_deviation  ) < EXTREMA_CUTOFF_THRESHOLD