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 |