Y a-t-il un système intégré numpy pour faire quelque chose comme ce qui suit? Autrement dit, prenez une liste d
et retournez une liste filtered_d
avec tous les éléments périphériques supprimés en fonction d'une répartition 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 des distributions variables (poisson, gaussien, etc.) et des seuils aberrants variables au sein de ces distributions (comme celui m
que j'ai utilisé ici).
Réponses:
Cette méthode est presque identique à la vôtre, juste plus numpyst (fonctionne également sur les tableaux numpy uniquement):
la source
m
est suffisamment grande (par exemplem=6
), mais pour de petites valeurs dem
celle-ci souffre du fait que la variance n'est pas des estimateurs robustes.Un élément important en ce qui concerne les valeurs aberrantes est que l'on devrait essayer d'utiliser des estimateurs aussi robustes que possible. La moyenne d'une distribution sera biaisée par les valeurs aberrantes mais, par exemple, la médiane sera beaucoup moins élevée.
S'appuyant sur la réponse d'eumiro:
Ici, j'ai remplacé la moyenne par la médiane la plus robuste et l'écart-type par la distance médiane absolue à la médiane. J'ai ensuite mis à l'échelle les distances en fonction de leur (à nouveau) valeur médiane afin que ce
m
soit sur une échelle relative raisonnable.Notez que pour que la
data[s<m]
syntaxe fonctionne, ildata
doit s'agir d'un tableau numpy.la source
3.5 / .6745 ~= 5.189
(ils se multiplients
par 0,6745 et spécifient unm
de 3,5 ... prennent égalementabs(s)
). Quelqu'un peut-il expliquer le choix de m? Ou est-ce quelque chose que vous identifierez à partir de votre ensemble de données particulier?m
des déclarations plutôt que duveteuses comme "l'interaction de la pureté et de l'efficacité"?TypeError: only integer scalar arrays can be converted to a scalar index
La réponse de Benjamin Bannier donne un passage lorsque la médiane des distances par rapport à la médiane est de 0, donc j'ai trouvé cette version modifiée un peu plus utile pour les cas donnés dans l'exemple ci-dessous.
Exemple:
Donne:
la source
S'appuyant sur Benjamin, en utilisant
pandas.Series
et en remplaçant MAD par IQR :Par exemple, si vous définissez
iq_range=0.6
, les percentiles de l'intervalle interquartile deviendraient :,0.20 <--> 0.80
donc plus de valeurs aberrantes seront incluses.la source
Une alternative consiste à faire une estimation robuste de l'écart type (en supposant des statistiques gaussiennes). En regardant les calculatrices en ligne, je vois que le 90% centile correspond à 1,2815σ et le 95% est 1,645σ ( http://vassarstats.net/tabs.html?#z )
À titre d'exemple simple:
Le résultat que j'obtiens est:
Ce qui est proche de la valeur attendue de 2.
Si nous voulons supprimer des points au-dessus / en dessous de 5 écarts-types (avec 1000 points, nous nous attendrions à 1 valeur> 3 écarts-types):
Qui donne:
Je n'ai aucune idée de l'approche la plus efficace / robuste
la source
Je voudrais fournir deux méthodes dans cette réponse, solution basée sur le "score z" et solution basée sur "IQR".
Le code fourni dans cette réponse fonctionne à la fois sur un
numpy
tableau dim simple et unnumpy
tableau multiple .Importons d'abord quelques modules.
méthode basée sur le score z
Cette méthode testera si le nombre se situe en dehors des trois écarts types. Sur la base de cette règle, si la valeur est aberrante, la méthode retournera true, sinon, retournera false.
Méthode basée sur l'IQR
Cette méthode testera si la valeur est inférieure
q1 - 1.5 * iqr
ou supérieure àq3 + 1.5 * iqr
, ce qui est similaire à la méthode de tracé de SPSS.Enfin, si vous souhaitez filtrer les valeurs aberrantes, utilisez un
numpy
sélecteur.Bonne journée.
la source
Considérez que toutes les méthodes ci-dessus échouent lorsque votre écart type devient très important en raison d'énormes valeurs aberrantes.
( Simalar car l'évaluation moyenne échoue et devrait plutôt évaluer la médiane. Cependant, la moyenne est "plus sujette à une erreur telle que stdDv". )
Vous pouvez essayer d'appliquer itérativement votre algorithme ou filtrer en utilisant l'intervalle interquartile: (ici "facteur" se rapporte à un intervalle * sigma, mais uniquement lorsque vos données suivent une distribution gaussienne)
la source
Je voulais faire quelque chose de similaire, sauf définir le nombre sur NaN plutôt que de le supprimer des données, car si vous le supprimez, vous modifiez la longueur, ce qui peut gâcher le traçage (c'est-à-dire si vous ne supprimez que les valeurs aberrantes d'une colonne dans une table , mais vous en avez besoin pour rester le même que les autres colonnes afin que vous puissiez les tracer les uns contre les autres).
Pour ce faire, j'ai utilisé les fonctions de masquage de numpy :
la source
si vous souhaitez obtenir la position d'index des valeurs aberrantes, vous la renverrez
idx_list
.la source
Pour un ensemble d' images (chaque image a 3 dimensions), où je voulais rejeter les valeurs aberrantes pour chaque pixel que j'ai utilisé:
Ensuite, il est possible de calculer la moyenne:
(Je l'utilise pour la soustraction de fond)
la source