ValueError: Eingabe enthält NaN, unendlich oder einen für dtype zu großen Wert ('float32')

41

Ich habe ValueError erhalten, als ich Testdaten mit einem RandomForest-Modell vorhersagte.

Mein Code:

clf = RandomForestClassifier(n_estimators=10, max_depth=6, n_jobs=1, verbose=2)
clf.fit(X_fit, y_fit)

df_test.fillna(df_test.mean())
X_test = df_test.values  
y_pred = clf.predict(X_test)

Der Fehler:

ValueError: Input contains NaN, infinity or a value too large for dtype('float32').

Wie finde ich die schlechten Werte im Testdatensatz? Ich möchte diese Datensätze auch nicht löschen. Kann ich sie einfach durch den Mittelwert oder den Median ersetzen?

Vielen Dank.

Edamame
quelle

Antworten:

44

Mit erhalten np.isnan(X)Sie eine Boolesche Maske zurück mit True für Positionen, die NaNs enthalten .

Mit np.where(np.isnan(X))bekommst du ein Tupel mit i, j Koordinaten von NaNs zurück.

Schließlich np.nan_to_num(X)ersetzen Sie mit "nan mit Null und inf mit endlichen Zahlen".

Alternativ können Sie Folgendes verwenden:

  • sklearn.impute.SimpleImputer für die mittlere / mittlere Imputation fehlender Werte oder
  • Pandas ' pd.DataFrame(X).fillna(), wenn Sie etwas anderes brauchen, als es mit Nullen zu füllen.
fernando
quelle
Ich bevor Identität Zustand nan für die Überprüfung, wenn x = x return None, np.isnan viele Male (x) für mich im Stich gelassen hatte, kann mich nicht erinnern , den Grund!
Itachi
1
Es ist nicht ratsam, NaN-Werte durch Nullen zu ersetzen. NaN-Werte haben möglicherweise immer noch eine Bedeutung für das Fehlen und das Zuweisen von Nullen ist wahrscheinlich das Schlechteste, was Sie tun können und die schlechteste Zuweisungsmethode, die Sie verwenden. Sie werden nicht nur willkürlich Nullen einfügen, die Ihre Variable verzerren könnten, sondern 0 ist möglicherweise nicht einmal ein akzeptabler Wert in Ihren Variablen, was bedeutet, dass Ihre Variable möglicherweise keine echte Null hat.
Hassam
Mir wurde klar, dass ich keine Anleitung gab. Wenn Sie Ihre Daten unterstellen möchten, verwenden Sie entweder einen gleitenden Durchschnitt mit .rolling(), um den fehlenden Wert durch den Mittelwert eines gleitenden Fensters zu ersetzen. Wenn Sie etwas Robusteres möchten, verwenden Sie das Modul <b> missingpy </ b>, das Sie MissForestfür eine zufallsbasierte Imputation verwenden können.
Husam
7

Angenommen, es X_testhandelt sich um einen Pandas-Datenrahmen, können Sie DataFrame.fillnadie NaN-Werte durch den Mittelwert ersetzen:

X_test.fillna(X_test.mean())
kmandov
quelle
X_test ist das Numpy-Array. Habe gerade den df_test in der ursprünglichen Frage aktualisiert, habe immer noch den gleichen Fehler ...
Edamame
6

Um das Original tatsächlich zu ändern, gehen Sie wie folgt vor:

X_test.fillna(X_train.mean(), inplace=True)

So überschreiben Sie das Original:

X_test = X_test.fillna(X_train.mean())

So prüfen Sie, ob Sie sich in einer Kopie oder in einer Ansicht befinden:

X_test._is_view
CommonSurname
quelle
2
Während dies technisch wahr ist, ist es praktisch falsch. Sie können die X_test-NAs nicht mit dem X_test-Mittelwert füllen, da Sie im wirklichen Leben nicht den X_test-Mittelwert haben, wenn Sie eine Stichprobe vorhersagen. Sie sollten den Mittelwert X_train verwenden, da dies die einzigen Daten sind, über die Sie tatsächlich verfügen (in 99% der Szenarien)
Omri374,
4

Nicht vergessen

col_mask=df.isnull().any(axis=0) 

Dadurch wird eine boolesche Maske zurückgegeben, die np.nan-Werte angibt.

row_mask=df.isnull().any(axis=1)

Was die Zeilen zurückgibt, in denen np.nan auftaucht. Dann können Sie durch einfaches Indizieren alle Ihre Punkte markieren, die np.nan sind.

df.loc[row_mask,col_mask]
bmc
quelle
2

Ich hatte ein ähnliches Problem und sah, dass Numpy mit NaN und Inf unterschiedlich umgeht.
Falls Ihre Daten Inf haben, versuchen Sie Folgendes:

np.where(x.values >= np.finfo(np.float64).max)
Where x is my pandas Dataframe 

Dies gibt ein Tupel von Orten an, an denen NA-Werte vorhanden sind.

Falls Ihre Daten Nan haben, versuchen Sie Folgendes:

np.isnan(x.values.any())
Prakash Vanapalli
quelle
2

Vergessen Sie nicht, auch nach inf-Werten zu suchen. Das einzige was bei mir geklappt hat:

df[df==np.inf]=np.nan
df.fillna(df.mean(), inplace=True)

Und noch besser, wenn Sie sklearn verwenden

def replace_missing_value(df, number_features):

    imputer = Imputer(strategy="median")
    df_num = df[number_features]
    imputer.fit(df_num)
    X = imputer.transform(df_num)
    res_def = pd.DataFrame(X, columns=df_num.columns)
    return res_def

Wenn number_features ein Array der number_features-Labels wäre, zum Beispiel:

number_features = ['median_income', 'gdp']
Kohn1001
quelle
-1

Ich hatte eine Nan im Etikettenobjekt. Also vergiss nicht, es zu überprüfen!

Srulik Ben-david
quelle
und verwendete df.dropna (subset = ['label'], inplace = True)
Srulik Ben-david vor
Hallo, willkommen bei Data Science StackExchange. Wenn Sie einen Beitrag beantworten, der bereits mehrere (hochrangige) Antworten enthält, stellen Sie bitte sicher, dass (i) Ihre Antwort etwas Neues bringt und (ii) die Frage beantwortet. In diesem Fall scheint Ihre Antwort nichts Neues zu bringen, und OP gab ausdrücklich an, dass das Löschen von Werten keine Option war.
Romain Reboulleau vor