394 Stimmen

Erkennen und Ausschließen von Ausreißern in einem Pandas DataFrame

Ich habe ein Pandas-Datenrahmen mit wenigen Spalten. Jetzt weiß ich, dass bestimmte Zeilen Ausreißer basierend auf einem bestimmten Spaltenwert sind. Zum Beispiel hat die Spalte Vol alle Werte um 12xx und ein Wert ist 4000 (Ausreißer). Ich möchte diese Zeilen ausschließen, die die Spalte Vol haben.

Also muss ich im Grunde einen Filter auf den Datenrahmen setzen, so dass wir alle Zeilen auswählen, in denen die Werte einer bestimmten Spalte innerhalb, sagen wir, 3 Standardabweichungen vom Mittelwert liegen.

Wie kann man das elegant erreichen?

9voto

mgoldwasser Punkte 12992

Eine weitere Option besteht darin, Ihre Daten so zu transformieren, dass die Auswirkungen von Ausreißern abgeschwächt werden. Dies können Sie durch Winsorizing Ihrer Daten tun.

import pandas as pd
from scipy.stats import mstats
%matplotlib inline

test_data = pd.Series(range(30))
test_data.plot()

Original data

# Werte auf das 5. und 95. Perzentil beschränken
transformed_test_data = pd.Series(mstats.winsorize(test_data, limits=[0.05, 0.05])) 
transformed_test_data.plot()

Winsorized data

7voto

Manualmsdos Punkte 1505

Sie können eine boolesche Maske verwenden:

import pandas as pd

def remove_outliers(df, q=0.05):
    upper = df.quantile(1-q)
    lower = df.quantile(q)
    mask = (df < upper) & (df > lower)
    return mask

t = pd.DataFrame({'train': [1,1,2,3,4,5,6,7,8,9,9],
                  'y': [1,0,0,1,1,0,0,1,1,1,0]})

mask = remove_outliers(t['train'], 0.1)

print(t[mask])

Ausgabe:

   train  y
2      2  0
3      3  1
4      4  1
5      5  0
6      6  0
7      7  1
8      8  1

3voto

Arun Punkte 166

Da ich mich noch am Anfang meiner Reise im Bereich Data Science befinde, behandele ich Ausreißer mit folgendem Code.

#Behandlung von Ausreißern

def outlier_detect(df):
    for i in df.describe().columns:
        Q1=df.describe().at['25%',i]
        Q3=df.describe().at['75%',i]
        IQR=Q3 - Q1
        LTV=Q1 - 1.5 * IQR
        UTV=Q3 + 1.5 * IQR
        x=np.array(df[i])
        p=[]
        for j in x:
            if j < LTV or j>UTV:
                p.append(df[i].median())
            else:
                p.append(j)
        df[i]=p
    return df

3voto

Dheeraj Punkte 891

Holen Sie sich das 98. und 2. Perzentil als Grenzwerte für unsere Ausreißer

upper_limit = np.percentile(X_train.logerror.values, 98) 
lower_limit = np.percentile(X_train.logerror.values, 2) # Filtern der Ausreißer aus dem DataFrame
data[‘Ziel’].loc[X_train[‘Ziel’]>oberes_limit] = oberes_limit data[‘Ziel’].loc[X_train[‘Ziel’]

2voto

Wagner Cipriano Punkte 1139

Ein vollständiges Beispiel mit Daten und 2 Gruppen folgt:

Imports:

from StringIO import StringIO
import pandas as pd
#pandas config
pd.set_option('display.max_rows', 20)

Beispiel mit Daten mit 2 Gruppen: G1: Gruppe 1. G2: Gruppe 2:

TESTDATEN = StringIO("""G1;G2;Wert
1;A;1.6
1;A;5.1
1;A;7.1
1;A;8.1

1;B;21.1
1;B;22.1
1;B;24.1
1;B;30.6

2;A;40.6
2;A;51.1
2;A;52.1
2;A;60.6

2;B;80.1
2;B;70.6
2;B;90.6
2;B;85.1
""")

Textdaten in Pandas DataFrame einlesen:

df = pd.read_csv(TESTDATEN, sep=";")

Definieren der Ausreißer unter Verwendung von Standardabweichungen

stds = 1.0
ausreißer = df[['G1', 'G2', 'Wert']].groupby(['G1','G2']).transform(
           lambda gruppe: (gruppe - gruppe.mean()).abs().div(gruppe.std())) > stds

Definieren der gefilterten Datenwerte und der Ausreißer:

dfv = df[ausreißer.Wert == False]
dfo = df[ausreißer.Wert == True]

Drucken Sie das Ergebnis:

print '\n'*5, 'Alle Werte mit Dezimalstelle 1 sind keine Ausreißer. Andererseits sind alle Werte mit 6 in der Dezimalstelle.'
print '\nDef DATA:\n%s\n\nGefilterte Werte mit %s stds:\n%s\n\nAusreißer:\n%s' %(df, stds, dfv, dfo)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X