ValueError: la entrada contiene NaN, infinito o un valor demasiado grande para dtype ('float32')


42

Obtuve ValueError al predecir datos de prueba usando un modelo RandomForest.

Mi código:

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)

El error:

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

¿Cómo encuentro los valores incorrectos en el conjunto de datos de prueba? Además, no quiero descartar estos registros, ¿puedo reemplazarlos con la media o la mediana?

Gracias.

Respuestas:


45

Con np.isnan(X)usted obtiene una máscara booleana con True para las posiciones que contienen NaNs.

Con np.where(np.isnan(X))usted recupera una tupla con las coordenadas i, j de NaNs.

Finalmente, con np.nan_to_num(X)usted "reemplace nan con cero e inf con números finitos".

Alternativamente, puede usar:

  • sklearn.impute.SimpleImputer para la imputación media / mediana de valores perdidos, o
  • pandas ' pd.DataFrame(X).fillna(), si necesita algo más que llenarlo con ceros.

Prefiero la condición de identidad para verificar nan, si x! = X return Ninguno, muchas veces np.isnan (x) me había fallado, no recuerdo la razón
Itachi

1
No es aconsejable reemplazar los valores de NaN con ceros. Los valores de NaN aún pueden tener importancia en faltar e imputarlos con ceros es probablemente lo peor que puede hacer y el peor método de imputación que utiliza. No solo introducirá ceros arbitrariamente que podrían sesgar su variable, sino que 0 podría no ser un valor aceptable en sus variables, lo que significa que su variable podría no tener un cero verdadero.
hussam

Me di cuenta de que no brindaba ninguna orientación. Si desea imputar sus datos, use un promedio variable .rolling()para reemplazar el valor perdido con el valor medio de una ventana variable. Si desea algo más robusto, use el módulo <b> missingpy </b>, puede usarlo MissForestpara una imputación basada en el bosque aleatorio.
hussam

7

Suponiendo que X_testes un marco de datos de pandas, puede usar DataFrame.fillnapara reemplazar los valores de NaN con la media:

X_test.fillna(X_test.mean())

X_test es la matriz numpy. Acabo de actualizar el df_test en la pregunta original, todavía recibí el mismo error ...
Edamame

7

Para cualquiera que esté pasando por esto, para modificar realmente el original:

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

Para sobrescribir el original:

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

Para verificar si está en una copia frente a una vista:

X_test._is_view

2
Si bien esto es cierto técnicamente, está mal prácticamente. No puede llenar los NA X_test con la media X_test, porque en la vida real no tendrá la media X_test cuando predice una muestra. Debería usar la media X_train porque estos son los únicos datos que realmente tiene a mano (en el 99% de los escenarios)
Omri374

4

No olvides

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

Que devuelve una máscara booleana que indica valores np.nan.

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

Que devuelven las filas donde apareció np.nan. Luego, mediante una indexación simple, puede marcar todos sus puntos que son np.nan.

df.loc[row_mask,col_mask]

3

No olvide comprobar también los valores inf. Lo único que funcionó para mí:

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

Y aún mejor si estás usando 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

Cuando number_features sería una matriz de las etiquetas number_features, por ejemplo:

number_features = ['median_income', 'gdp']

2

Me enfrenté a un problema similar y vi que numpy maneja NaN e Inf de manera diferente.
En caso de que sus datos tengan Inf, intente esto:

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

Esto dará una tupla de ubicación de lugares donde los valores de NA están presentes.

En caso de que sus datos tengan Nan, intente esto:

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

1

En la mayoría de los casos, deshacerse de los valores infinitos y nulos resuelve este problema.

deshacerse de los valores infinitos.

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

deshacerse de los valores nulos de la manera que desee, valores específicos como 999, mean o crear su propia función para imputar valores perdidos

df.fillna(999, inplace=True)

o

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


Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.