首页 > 解决方案 > 我正在尝试使用 numpy 模块创建和实现一个识别 Python 数据集中异常值的函数,不断收到“ValueError”

问题描述

我正在尝试创建一个“异常值”函数来检测数据集中的异常值。然后我试图将该函数调用到一个 for 循环中,但它一直给我一个ValueError. 我对错误发生的原因有一个简要的了解。这是因为 numpy 不允许您将数组设置为布尔值(如果我错了,请纠正我)。我只是想知道是否有办法解决这个问题,以及我将如何实施错误给我的建议a.any()a.all()

代码:

import numpy as np

def Outlier(a, IQR, Q1, Q3):
    if a < Q1 - 1.5 * IQR or a > Q3 + 1.5 * IQR:    
        outlier = True
    else:
        outlier = False        
    return(outlier)


data_clean = []

Q1 = np.percentile(data, 25)
Q3 = np.percentile(data, 75)

print("Q1 = {:,.2f}".format(Q1)) 
print("Q3 = {:,.2f}".format(Q3)) 

n= len(data)

for i in range(n): 
    outlier[i] = Outlier(data, IQR, Q1, Q3) # Error

    if outlier[i] == False : # Error
        data_clean.append(data[i])
    else:
        print("value removed (outlier) = {:,.2f}".format(data[i]))

data_clean = np.asarray(data_clean)
n = len(data_clean) 
print("n = {:.0f}".format(n)) 

print("data_clean = {}".format(data_clean))

完整错误:

ValueError                                Traceback (most recent call last)
<ipython-input-30-f686bd0a0718> in <module>

---> 19     outlier[i] = Outlier(data, IQR, Q1, Q3)
---> 20     if outlier[i] == False :            #check for outlier

<ipython-input-29-1f034e2a09b6> in Outlier(a, IQR, Q1, Q3)
3 def Outlier(a, IQR, Q1, Q3):
4
---> 5     if a < Q1 - 1.5 * IQR or a > Q3 + 1.5 * IQR:
6
7              outlier = True
ValueError: The truth value of an array with more than one element is ambiguous.
Use a.any() or a.all()

提前致谢。只是为了澄清上面的代码是为了检查数据集中的异常值,然后将非异常值添加到data_clean列表中,使数据集没有异常值。

标签: pythonnumpystatisticsdataset

解决方案


我认为,除了迭代之外,您可以在函数内部执行所有操作而无需循环:

import numpy as np

def detect_outliers(arr, pct_bounds=(75, 25), mulitplier=1.5):
    upper, lower = np.percentile(arr, pct_bounds)
    spread = upper - lower
    # Create a mask where the data are more than or less than 1.5 * IQR from the median
    mask = (arr < (np.median(arr) - (multiplier * spread))) | (arr > (np.median(arr) + (multiplier * spread)))
    outliers = arr[mask]
    # Invert mask
    new_array = arr[~mask]
    return outliers, new_array

test_data = np.random.normal(size=100)
outliers, data = detect_outliers(test_data)

推荐阅读