Gibt es eine eingebaute Nummer, um so etwas wie das Folgende zu tun? Nehmen Sie also eine Liste d
und geben Sie eine Liste zurück, filtered_d
in der alle äußeren Elemente entfernt wurden, basierend auf einer angenommenen Verteilung der Punkte in 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]
Ich sage 'so etwas wie', weil die Funktion möglicherweise unterschiedliche Verteilungen (Poisson, Gauß usw.) und unterschiedliche Ausreißerschwellen innerhalb dieser Verteilungen (wie die m
hier verwendeten) zulässt .
Antworten:
Diese Methode ist fast identisch mit Ihrer, nur mehr Numpyste (funktioniert auch nur bei Numpy-Arrays):
quelle
m
ausreichend groß ist (z. B.m=6
), aber für kleine Wertem
leidet dies unter dem Mittelwert, dass die Varianz keine robusten Schätzer sind.Im Umgang mit Ausreißern ist es wichtig, Schätzer so robust wie möglich einzusetzen. Der Mittelwert einer Verteilung wird durch Ausreißer verzerrt, aber z. B. ist der Median viel geringer.
Aufbauend auf Eumiros Antwort:
Hier habe ich den Mittelwert durch den robusteren Median und die Standardabweichung durch den absoluten Medianabstand zum Median ersetzt. Ich habe dann die Abstände um ihren (erneuten) Medianwert skaliert, so dass dies
m
auf einer vernünftigen relativen Skala liegt.Beachten Sie, dass die
data[s<m]
Syntaxdata
ein Numpy-Array sein muss , damit die Syntax funktioniert .quelle
3.5 / .6745 ~= 5.189
(sie multiplizierens
mit .6745 und geben einm
von 3.5 an ... nehmen auchabs(s)
). Kann jemand die Wahl von m erklären? Oder ist es etwas, das Sie anhand Ihres speziellen Datensatzes identifizieren werden?m
flauschige Aussagen wie "Zusammenspiel von Reinheit und Effizienz" geben?TypeError: only integer scalar arrays can be converted to a scalar index
Die Antwort von Benjamin Bannier ergibt einen Durchgang, wenn der Median der Abstände vom Median 0 ist. Daher fand ich diese modifizierte Version für Fälle, wie im folgenden Beispiel angegeben, etwas hilfreicher.
Beispiel:
Gibt:
quelle
Aufbauend auf Benjamins, Verwendung
pandas.Series
und Ersetzung von MAD durch IQR :Wenn Sie beispielsweise festlegen
iq_range=0.6
, werden die Perzentile des Interquartilbereichs zu :0.20 <--> 0.80
, sodass mehr Ausreißer eingeschlossen werden.quelle
Eine Alternative besteht darin, eine robuste Schätzung der Standardabweichung vorzunehmen (unter der Annahme einer Gaußschen Statistik). Wenn ich Online-Rechner nachschaue, sehe ich, dass das 90% -Perzentil 1,2815σ entspricht und das 95% -Interil 1,645σ ( http://vassarstats.net/tabs.html?#z ).
Als einfaches Beispiel:
Die Ausgabe, die ich bekomme, ist:
Welches ist in der Nähe des erwarteten Wertes von 2.
Wenn wir Punkte über / unter 5 Standardabweichungen entfernen möchten (mit 1000 Punkten würden wir 1 Wert> 3 Standardabweichungen erwarten):
Welches gibt:
Ich habe keine Ahnung, welcher Ansatz effizienter / robuster ist
quelle
Ich möchte in dieser Antwort zwei Methoden angeben, eine Lösung basierend auf "z score" und eine Lösung basierend auf "IQR".
Der in dieser Antwort angegebene Code funktioniert sowohl für einzelne Dim-
numpy
Arrays als auch für mehrerenumpy
Arrays.Importieren wir zunächst einige Module.
z Score-basierte Methode
Diese Methode prüft, ob die Anzahl außerhalb der drei Standardabweichungen liegt. Basierend auf dieser Regel gibt die Methode true zurück, wenn der Wert ein Ausreißer ist. Wenn nicht, wird false zurückgegeben.
IQR-basierte Methode
Diese Methode prüft, ob der Wert kleiner
q1 - 1.5 * iqr
oder größer als istq3 + 1.5 * iqr
, was der Plotmethode von SPSS ähnlich ist.Wenn Sie die Ausreißer herausfiltern möchten, verwenden Sie einen
numpy
Selektor.Einen schönen Tag noch.
quelle
Bedenken Sie, dass alle oben genannten Methoden fehlschlagen, wenn Ihre Standardabweichung aufgrund großer Ausreißer sehr groß wird.
( Simalar, da die durchschnittliche Berechnung fehlschlägt und eher den Median berechnen sollte. Der Durchschnitt ist jedoch "anfälliger für Fehler wie stdDv". )
Sie könnten versuchen, Ihren Algorithmus iterativ anzuwenden, oder Sie filtern nach dem Interquartilbereich: (hier bezieht sich "Faktor" auf einen * Sigma-Bereich, jedoch nur, wenn Ihre Daten einer Gaußschen Verteilung folgen)
quelle
Ich wollte etwas Ähnliches tun, außer die Nummer auf NaN zu setzen, anstatt sie aus den Daten zu entfernen, da Sie beim Entfernen die Länge ändern, die das Plotten durcheinander bringen kann (dh wenn Sie nur Ausreißer aus einer Spalte in einer Tabelle entfernen , aber Sie müssen es mit den anderen Spalten identisch halten, damit Sie sie gegeneinander zeichnen können.
Dazu habe ich die Maskierungsfunktionen von numpy verwendet :
quelle
Wenn Sie die Indexposition der Ausreißer erhalten möchten,
idx_list
wird diese zurückgegeben.quelle
Für eine Reihe von Bildern (jedes Bild hat 3 Dimensionen), bei denen ich Ausreißer für jedes verwendete Pixel ablehnen wollte:
Dann ist es möglich, den Mittelwert zu berechnen:
(Ich benutze es für die Hintergrundsubtraktion)
quelle