ValueError: a entrada contém NaN, infinito ou um valor muito grande para dtype ('float32')

41

Eu obtive o ValueError ao prever dados de teste usando um modelo RandomForest.

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

O erro:

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

Como encontro os valores incorretos no conjunto de dados de teste? Além disso, não quero descartar esses registros. Posso apenas substituí-los pela média ou mediana?

Obrigado.

Edamame
fonte

Respostas:

45

Com np.isnan(X)você começa uma volta máscara booleano com True para posições contendo NaNs.

Com np.where(np.isnan(X))você, você volta uma tupla com i, j coordenadas de NaNs.

Finalmente, com np.nan_to_num(X)você "substitua nan por zero e inf por números finitos".

Como alternativa, você pode usar:

  • sklearn.impute.SimpleImputer para imputação média / mediana de valores ausentes ou
  • pandas ' pd.DataFrame(X).fillna(), se você precisar de algo diferente de preenchê-lo com zeros.
fernando
fonte
Eu prefiro condição de identidade para verificar nan, se x = x retorno Nenhum, muitas vezes np.isnan (x) não tinha conseguido para mim, não me lembro o motivo!
Itachi
11
Não é aconselhável substituir os valores de NaN por zeros. Os valores de NaN ainda podem ter significado em estar faltando e imputá-los com zeros é provavelmente a pior coisa que você pode fazer e o pior método de imputação usado. Você não apenas introduzirá zeros arbitrariamente, o que pode distorcer sua variável, mas 0 pode até não ser um valor aceitável em suas variáveis, o que significa que sua variável pode não ter um zero verdadeiro.
hussam
Percebi que não forneci nenhuma orientação. Se você deseja imputar seus dados, use uma média móvel usando .rolling()para substituir o valor ausente pelo valor médio de uma janela contínua. Se você quiser algo mais robusto, use o módulo <b> missingpy </b>, MissForestpara uma imputação baseada em floresta aleatória.
hussam
7

Supondo que X_testseja um dataframe de pandas, você pode usar DataFrame.fillnapara substituir os valores de NaN pela média:

X_test.fillna(X_test.mean())
kmandov
fonte
X_test é a matriz numpy. Acaba de atualizar o df_test na pergunta original, ainda tenho o mesmo erro ...
Edamame
6

Para alguém que esteja passando por isso, para modificar o original:

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

Para substituir o original:

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

Para verificar se você está em uma cópia versus uma visualização:

X_test._is_view
CommonSurname
fonte
2
Embora isso seja verdade tecnicamente, está errado na prática. Você não pode preencher os X_test NAs com a média X_test, porque na vida real você não terá a média X_test quando estiver prevendo uma amostra. Você deve usar a média X_train porque este é os únicos dados que você realmente tem na mão (em 99% dos cenários)
Omri374
4

Não esqueça

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

O que retorna uma máscara booleana indicando valores np.nan.

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

Que retornam as linhas em que np.nan apareceu. Então, através da indexação simples, você pode sinalizar todos os seus pontos que são np.nan.

df.loc[row_mask,col_mask]
bmc
fonte
2

Eu enfrentei um problema semelhante e vi que o numpy lida com NaN e Inf de maneira diferente.
No caso de seus dados terem Inf, tente o seguinte:

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

Isso fornecerá uma tupla de localização dos locais onde os valores de NA estão presentes.

No caso de seus dados terem Nan, tente o seguinte:

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

Não se esqueça de verificar também os valores inf. A única coisa que funcionou para mim:

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

E melhor ainda, se você estiver usando o 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

Quando number_features seria uma matriz dos rótulos number_features, por exemplo:

number_features = ['median_income', 'gdp']
Kohn1001
fonte