ValueError: l'entrée contient NaN, l'infini ou une valeur trop grande pour dtype ('float32')


42

J'ai obtenu ValueError lors de la prévision de données de test à l'aide d'un modèle RandomForest.

Mon 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)

L'erreur:

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

Comment trouver les mauvaises valeurs dans le jeu de données test? De plus, je ne veux pas supprimer ces enregistrements. Puis-je simplement les remplacer par la moyenne ou la médiane?

Merci.

Réponses:


45

Avec np.isnan(X)vous obtenez un masque booléen avec True pour les positions contenant NaNs.

Avec np.where(np.isnan(X))vous récupérez un tuple avec i, j les coordonnées de NaNs.

Enfin, avec np.nan_to_num(X)vous "remplacez nan par zéro et inf par des nombres finis".

Alternativement, vous pouvez utiliser:

  • sklearn.impute.SimpleImputer pour l'imputation moyenne / médiane des valeurs manquantes, ou
  • pandas » pd.DataFrame(X).fillna(), si vous avez besoin de quelque chose d'autre que de le remplir avec des zéros.

Je préfère la condition d'identité pour vérifier nan, si x! = X return Aucun, plusieurs fois que np.isnan (x) a échoué pour moi, je ne me souviens pas de la raison
Itachi le

1
Il est déconseillé de remplacer les valeurs de NaN par des zéros. Les valeurs NaN peuvent toujours avoir une signification en manquant et en les imputant avec des zéros est probablement la pire chose que vous puissiez faire et la pire méthode d'imputation que vous utilisez. Non seulement vous introduirez des zéros de manière arbitraire, ce qui pourrait biaiser votre variable, mais 0 pourrait même ne pas être une valeur acceptable dans vos variables, ce qui signifie que votre variable pourrait ne pas avoir un zéro absolu.
Hussam

J'ai réalisé que je ne fournissais aucune orientation. Si vous souhaitez imputer vos données, utilisez une moyenne glissante en utilisant .rolling()pour remplacer la valeur manquante par la valeur moyenne d'une fenêtre glissante. Si vous voulez quelque chose de plus robuste, utilisez le module <b> missingpy </ b>, que vous pouvez utiliser MissForestpour une imputation aléatoire basée sur une forêt.
Hussam

7

En supposant qu’il X_tests’agisse d’une base de données de pandas, vous pouvez utiliser DataFrame.fillnapour remplacer les valeurs de NaN par la moyenne:

X_test.fillna(X_test.mean())

X_test est le tableau numpy. Vient de mettre à jour le test df_test dans la question initiale, toujours la même erreur ...
Edamame

7

Pour quiconque passe à travers cela, pour réellement modifier l'original:

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

Pour écraser l'original:

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

Pour vérifier si vous êtes dans une copie par rapport à une vue:

X_test._is_view

2
Bien que cela soit vrai techniquement, c'est pratiquement faux. Vous ne pouvez pas renseigner les NA de X_test avec la moyenne X_test, car dans la vie réelle, vous ne disposez pas de la moyenne X_test lorsque vous prédit un échantillon. Vous devez utiliser la moyenne X_train car il s'agit des seules données que vous avez réellement en main (dans 99% des scénarios)
Omri374

4

N'oublie pas

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

Ce qui retourne un masque booléen indiquant les valeurs np.nan.

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

Qui retournent les lignes où np.nan est apparu. Ensuite, par simple indexation, vous pouvez marquer tous vos points np.nan.

df.loc[row_mask,col_mask]

3

N'oubliez pas de vérifier également les valeurs inf. La seule chose qui a fonctionné pour moi:

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

Et encore mieux si vous utilisez Sklearn

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

Lorsque number_features serait un tableau des étiquettes number_features, par exemple:

number_features = ['median_income', 'gdp']

2

J'ai rencontré un problème similaire et j'ai vu que Numpy gère NaN et Inf différemment.
Si vos données ont Inf, essayez ceci:

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

Cela donnera un tuple d'emplacement des endroits où les valeurs de NA sont présentes.

Incase si vos données ont Nan, essayez ceci:

np.isnan(x.values.any())

1

Dans la plupart des cas, l'élimination des valeurs infinies et nulles résout ce problème.

se débarrasser des valeurs infinies.

df.replace([np.inf, -np.inf], np.nan, inplace=True)

éliminez les valeurs nulles comme vous le souhaitez, des valeurs spécifiques telles que 999, la moyenne, ou créez votre propre fonction pour imputer les valeurs manquantes

df.fillna(999, inplace=True)

ou

df.fillna(df.mean(), inplace=True)


En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.