按列从numpy数组中删除离群值

时间:2020-05-12 10:08:49

标签: python arrays numpy for-loop outliers

我有一个很大的数据集(超过10k列),除了一些离群值之外,其值几乎落在同一范围内。我需要删除这些离群值。 考虑以下示例:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

data = np.array([(1,18,1,1,1,1),
                 (1,18,2,3,2,1),
                 (1,22,1,2,2,2),
                 (2,22,3,1,3,1),
                 (1,19,1,10,10,3),
                 (1,22,3,2,1,3),
                 (10,20,3,1,3,10),
                 (2,20,1,3,2,1)])

如果创建每个列的箱线图,我可以清楚地看到异常值。

df = pd.DataFrame(data, columns=['a','b','c','d','e','f'])
sns.boxplot(x="variable", y="value", data=pd.melt(df))
plt.show()

enter image description here

目标是逐列遍历数组,并在每次将其标记为该变量(列)的异常值时删除行。 这将删除第4/7和6/7行。 我一直在努力进行以下工作:

for i in range(data.shape[1]):
    mean = np.mean(data[:,i])
    print(mean)
    standard_deviation = np.std(data[:,i])
    print(standard_deviation)
    distance_from_mean = abs(data[:,i] - mean)
    max_deviations = 2
    not_outlier = distance_from_mean < max_deviations * standard_deviation
    data[:,i] = data[:,i][not_outlier]

哪个会产生以下错误: “ ValueError:无法将输入数组从形状(7)广播到形状(8)”

我对数组索引的理解不足,我认为这是错误的。或者也许有更好的方法来实现这一目标?

谢谢!

1 个答案:

答案 0 :(得分:1)

首先使用numpy.any查找包含异常值的行,然后将其丢弃。

import numpy as np

data = np.array(
    [
        [1, 1, 1, 1, 1, 1],
        [2, 1, 2, 1, 2, 3],
        [1, 3, 1, 2, 2, 2],
        [2, 2, 3, 1, 3, 1],
        [1, 1, 1, 10, 10, 3],
        [1, 2, 3, 2, 1, 3],
        [10, 2, 3, 1, 3, 10],
        [2, 2, 1, 3, 2, 1],
    ]
)

threshold = 5
has_outlier = np.any(data > threshold, axis=1)
data = data[~has_outlier]