134 votes

Existe-t-il un utilitaire numpy pour rejeter les valeurs aberrantes d'une liste ?

Existe-t-il un buildin numpy pour faire quelque chose comme ce qui suit ? C'est-à-dire, prendre une liste d et retourner une liste filtered_d en éliminant tous les éléments aberrants sur la base d'une distribution supposée des points dans d .

import numpy as np

def reject_outliers(data):
    m = 2
    u = np.mean(data)
    s = np.std(data)
    filtered = [e for e in data if (u - 2 * s < e < u + 2 * s)]
    return filtered

>>> d = [2,4,5,1,6,5,40]
>>> filtered_d = reject_outliers(d)
>>> print filtered_d
[2,4,5,1,6,5]

Je dis "quelque chose comme" parce que la fonction pourrait permettre de varier les distributions (poisson, gaussienne, etc.) et de varier les seuils des valeurs aberrantes au sein de ces distributions (comme la fonction m que j'ai utilisé ici).

0voto

Caner Erden Points 166

Si vous voulez obtenir la position de l'indice des valeurs aberrantes. idx_list le rendra.

def reject_outliers(data, m = 2.):
        d = np.abs(data - np.median(data))
        mdev = np.median(d)
        s = d/mdev if mdev else 0.
        data_range = np.arange(len(data))
        idx_list = data_range[s>=m]
        return data[s<m], idx_list

data_points = np.array([8, 10, 35, 17, 73, 77])  
print(reject_outliers(data_points))

after rejection: [ 8 10 35 17], index positions of outliers: [4 5]

0voto

ron653 Points 5

Pour un ensemble de images (chaque image a 3 dimensions), où je voulais rejeter les valeurs aberrantes pour chaque pixel utilisé :

mean = np.mean(imgs, axis=0)
std = np.std(imgs, axis=0)
mask = np.greater(0.5 * std + 1, np.abs(imgs - mean))
masked = np.multiply(imgs, mask)

Il est alors possible de calculer la moyenne :

masked_mean = np.divide(np.sum(masked, axis=0), np.sum(mask, axis=0))

(Je l'utilise pour la soustraction d'arrière-plan)

0voto

Yaroslav Points 809

Coupe les valeurs aberrantes dans un tableau numpy le long de l'axe et les remplace par les valeurs min ou max le long de cet axe, selon ce qui est le plus proche. Le seuil est le z-score :

def np_z_trim(x, threshold=10, axis=0):
    """ Replace outliers in numpy ndarray along axis with min or max values
    within the threshold along this axis, whichever is closer."""
    mean = np.mean(x, axis=axis, keepdims=True)
    std = np.std(x, axis=axis, keepdims=True)
    masked = np.where(np.abs(x - mean) < threshold * std, x, np.nan)
    min = np.nanmin(masked, axis=axis, keepdims=True)
    max = np.nanmax(masked, axis=axis, keepdims=True)
    repl = np.where(np.abs(x - max) < np.abs(x - min), max, min)
    return np.where(np.isnan(masked), repl, masked)

0voto

Johnny V Points 409

Ma solution laisse tomber les percentiles supérieurs et inférieurs, en gardant les valeurs qui sont égales à la limite :

def remove_percentile_outliers(data, percent_to_drop=0.001):
    low, high = data.quantile([percent_to_drop / 2, 1-percent_to_drop / 2])
    return data[(data >= low )&(data <= high)]

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X