首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用于返回二维numpy数组中的异常值索引的Python函数

用于返回二维numpy数组中的异常值索引的Python函数
EN

Stack Overflow用户
提问于 2018-11-15 13:02:49
回答 3查看 1.6K关注 0票数 1

有没有办法用Python编写一个函数,它读取一个numpy二维数组,找到任何异常值的索引值,然后返回一个包含这些索引值的数组?

这就是我到目前为止所拥有的。我尝试使用Z-score方法:

代码语言:javascript
复制
import numpy as np

def function(arrayMatrix):
    threshold = 3
    mean_y = np.mean(arrayMatrix)
    stdev_y = np.std(arrayMatrix)
    z_scores = [(y - mean_y) / stdev_y for y in arrayMatrix]
    return np.where(np.abs(z_scores) > threshold)



def main():
    MatrixOne = np.array([[1,2,10],[1,10,2]])   
    print(function(MatrixOne))

    MatrixTwo = np.array([[1,2,3,4,20],[1,20,2,3,4],[20,2,3,4,5]])
    print(function(MatrixTwo))

main()

结果将是:

代码语言:javascript
复制
[2 1]
[4 1 0]

我的结果是:

代码语言:javascript
复制
(array([], dtype=int32), array([], dtype=int32))
(array([], dtype=int32), array([], dtype=int32))
EN

回答 3

Stack Overflow用户

发布于 2018-11-15 13:31:14

你问了一个非常好的问题。您可以使用python删除异常值的interquartile range (IQR)方法。=)

查看这段代码。可以调整名为outlierConstant的变量以增加(或减小)对异常值的容差。我选择了outlierConstant=0.5作为我在这里给出的例子。

代码语言:javascript
复制
import numpy as np

# iqr is a function which returns indices of outliers in each row/1d array
def iqr(a, outlierConstant):
    """
    a : numpy.ndarray (array from which outliers have to be removed.)
    outlierConstant : (scale factor around interquartile region.)                         
    """
    num = a.shape[0]

    upper_quartile = np.percentile(a, 75)
    lower_quartile = np.percentile(a, 25)
    IQR = (upper_quartile - lower_quartile) * outlierConstant
    quartileSet = (lower_quartile - IQR, upper_quartile + IQR)

    outlier_indx = []
    for i in range(num):
        if a[i] >= quartileSet[0] and a[i] <= quartileSet[1]: pass
        else: outlier_indx += [i]            

    return outlier_indx  


def function(arr):
    lst = []
    for i in range(arr.shape[0]):
        lst += iqr(a = arr[i,:], outlierConstant=0.5) 
    return lst

def main():
    MatrixOne = np.array([[1,2,10],[1,10,2]])   
    print(function(MatrixOne))

    MatrixTwo = np.array([[1,2,3,4,20],[1,20,2,3,4],[20,2,3,4,5]])
    print(function(MatrixTwo))

main()

输出

代码语言:javascript
复制
[2, 1]
[4, 1, 0]
票数 2
EN

Stack Overflow用户

发布于 2018-11-15 13:37:36

异常值是一组测量值,与平均值的偏差超过两个标准差,与平均值的偏差超过三个标准差。在您的情况下,您可以将通过标准差的差异定义为异常值。

试试这个:

代码语言:javascript
复制
import numpy as np

def main():
    MatrixOne = np.array([[1,2,10],[1,10,2]])   
    print(function(MatrixOne))

    MatrixTwo = np.array([[1,2,3,4,20],[1,20,2,3,4],[20,2,3,4,5]])
    print(function(MatrixTwo))

    MatrixThree = np.array([[1,10,2,8,5],[2,7,3,9,11],[19,2,1,1,5]]) 
    print(function(MatrixThree))   



def function(arrayMatrix):
    arraystd=np.std(arrayMatrix,1,ddof=1,keepdims=True)
    arraymean=np.mean(arrayMatrix,1)[:, np.newaxis]
    arrayoutlier=np.transpose(np.where(np.abs(arrayMatrix-arraymean)>(arraystd)))#or 2*arraystd)
    return arrayoutlier

main()

输出:

代码语言:javascript
复制
   [[0 2]
 [1 1]]
[[0 4]
 [1 1]
 [2 0]]
[[0 0]
 [0 1]
 [1 0]
 [1 4]
 [2 0]]

程序返回的索引是尺寸坐标。

票数 0
EN

Stack Overflow用户

发布于 2018-11-15 14:21:19

您的数学计算是正确的(尽管您需要设置threshold=1才能获得您想要的结果),但是您对Numpy数组的使用有点不对劲。下面是如何修复代码的方法:

代码语言:javascript
复制
import numpy as np

def function(arrayMatrix, threshold=1):
    zscore = (arrayMatrix - arrayMatrix.mean())/arrayMatrix.std()
    return np.where(np.abs(zscore) > threshold)

def main():
    MatrixOne = np.array([[1,2,10],[1,10,2]])   
    print(function(MatrixOne))

    MatrixTwo = np.array([[1,2,3,4,20],[1,20,2,3,4],[20,2,3,4,5]])
    print(function(MatrixTwo))

    MatrixThree = np.array([[1,10,2,8,5],[2,7,3,9,11],[19,2,1,1,5]])
    print(function(MatrixThree))

main()

这将输出以下内容:

代码语言:javascript
复制
(array([0, 1]), array([2, 1]))
(array([0, 1, 2]), array([4, 1, 0]))
(array([1, 2]), array([4, 0]))

其中每行中的第一个数组是离群值的行索引,第二个数组是列索引。例如,输出中的第一行告诉您MatrixOne中的异常值为:

代码语言:javascript
复制
outliers = [MatrixOne[0,2], MatrixOne[1,1]]
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53312719

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档