Erkennen und Filtern von Ausreißern¶
Das Filtern oder Transformieren von Ausreißern ist weitgehend eine Frage der Anwendung von Array-Operationen. Betrachtet einen DataFrame mit einigen normal verteilten Daten:
[1]:
import numpy as np
import pandas as pd
df = pd.DataFrame(np.random.randn(1000, 4))
df.describe()
[1]:
0 | 1 | 2 | 3 | |
---|---|---|---|---|
count | 1000.000000 | 1000.000000 | 1000.000000 | 1000.000000 |
mean | 0.003064 | 0.096247 | 0.056972 | -0.020452 |
std | 1.008448 | 0.976915 | 1.004594 | 1.010706 |
min | -3.208608 | -3.209683 | -2.950671 | -3.386906 |
25% | -0.708152 | -0.599949 | -0.647935 | -0.680458 |
50% | 0.041351 | 0.105793 | 0.060608 | -0.023031 |
75% | 0.680191 | 0.731972 | 0.751053 | 0.625897 |
max | 3.226749 | 3.221513 | 3.257586 | 3.604722 |
Angenommen, ihr wollt in einer der Spalten Werte finden, deren absoluter Wert größer als 3 oder kleiner als -3 ist:
[2]:
col = df[1]
col[col.abs() > 3]
[2]:
219 -3.209683
411 3.140193
934 3.221513
Name: 1, dtype: float64
Um alle Zeilen auszuwählen, in denen Wert größer 3 oder kleiner -3 in einer der Spalten ist, könnt ihr pandas.DataFrame.any auf einen booleschen DataFrame anwenden, wobei mit any(axis=1)
üüberprüft wird, ob ein Wert in einer Zeile wahr ist:
[3]:
df[(df.abs() > 3).any(axis=1)]
[3]:
0 | 1 | 2 | 3 | |
---|---|---|---|---|
95 | 3.226749 | -1.579194 | -0.719229 | 0.214088 |
101 | 0.562001 | 0.333124 | 1.559934 | -3.215258 |
219 | 1.083981 | -3.209683 | -0.667363 | -1.438619 |
279 | -0.494579 | -0.864461 | 1.278015 | 3.409804 |
348 | -0.090586 | -2.045006 | 0.065500 | 3.604722 |
411 | 1.552122 | 3.140193 | 2.438573 | -1.334575 |
467 | 3.188898 | -0.407706 | -0.120590 | 0.630946 |
615 | -0.168051 | 0.312383 | 1.491362 | -3.386906 |
675 | -3.208608 | -0.314907 | 0.734751 | -0.126330 |
685 | 1.669532 | 0.266478 | -1.005036 | 3.066603 |
928 | 0.272368 | 0.535655 | 3.257586 | 1.425122 |
934 | 0.246128 | 3.221513 | 0.310442 | -2.481366 |
945 | -3.086749 | -2.254744 | 0.799249 | 0.689478 |
Auf dieser Grundlage können die Werte begrenzt werden auf ein Intervall zwischen -3
und 3
. Hierfür verwenden wir die Anweisung np.sign(df)
, die Werte 1
und -1
erzeugt, je nachdem, ob die Werte in df
positiv oder negativ sind:
[4]:
df[df.abs() > 3] = np.sign(df) * 3
df.describe()
[4]:
0 | 1 | 2 | 3 | |
---|---|---|---|---|
count | 1000.000000 | 1000.000000 | 1000.000000 | 1000.000000 |
mean | 0.002944 | 0.096095 | 0.056714 | -0.020931 |
std | 1.006261 | 0.975114 | 1.003805 | 1.005317 |
min | -3.000000 | -3.000000 | -2.950671 | -3.000000 |
25% | -0.708152 | -0.599949 | -0.647935 | -0.680458 |
50% | 0.041351 | 0.105793 | 0.060608 | -0.023031 |
75% | 0.680191 | 0.731972 | 0.751053 | 0.625897 |
max | 3.000000 | 3.000000 | 3.000000 | 3.000000 |