ValueError: l'input contiene NaN, infinito o un valore troppo grande per dtype ('float32')


42

Ho ottenuto ValueError durante la previsione dei dati di test utilizzando un modello RandomForest.

Il mio codice:

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'errore:

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

Come trovo i valori errati nel set di dati di test? Inoltre, non voglio eliminare questi record, posso semplicemente sostituirli con la media o la mediana?

Grazie.

Risposte:


45

Con np.isnan(X)te ottieni una maschera booleana con True per le posizioni contenenti NaNs.

Con np.where(np.isnan(X))te ritorni una tupla con i, j coordinate di NaNs.

Infine, con np.nan_to_num(X)te "sostituisci nan con zero e inf con numeri finiti".

In alternativa, puoi usare:

  • sklearn.impute.SimpleImputer per imputazione media / mediana dei valori mancanti, o
  • panda ' pd.DataFrame(X).fillna(), se hai bisogno di qualcosa di diverso dal riempirlo di zeri.

Preferisco la condizione di identità per controllare nan, se x! = X return Nessuno, molte volte np.isnan (x) non è riuscito per me, non ricordo il motivo
— Itachi,

1
Non è consigliabile sostituire i valori NaN con zeri. I valori di NaN potrebbero ancora avere un significato nel perdere e imputarli con zeri è probabilmente la cosa peggiore che puoi fare e il peggior metodo di imputazione che usi. Non solo introdurrai arbitrariamente degli zeri che potrebbero distorcere la tua variabile, ma 0 potrebbe anche non essere un valore accettabile nelle tue variabili, il che significa che la tua variabile potrebbe non avere un vero zero.
— hussam,

Mi sono reso conto che non avevo fornito alcuna guida. Se si desidera imputare i dati utilizzare una media mobile usando .rolling()per sostituire il valore mancante con il valore medio di una finestra mobile. Se vuoi qualcosa di più robusto usa il modulo <b> missingpy </b> che puoi usare MissForestper un'imputazione basata sulla foresta casuale.
— hussam,

7

Supponendo che X_testsia un frame di dati panda, è possibile utilizzare DataFrame.fillnaper sostituire i valori NaN con la media:

X_test.fillna(X_test.mean())

X_test è l'array numpy. Ho appena aggiornato il df_test nella domanda originale, ho ancora ricevuto lo stesso errore ...
— Edamame,

7

Per chiunque accada attraverso questo, per modificare effettivamente l'originale:

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

Per sovrascrivere l'originale:

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

Per verificare se sei in una copia rispetto a una vista:

X_test._is_view

2
Mentre questo è vero tecnicamente, praticamente è sbagliato. Non puoi riempire i NA X_test con la media X_test, perché nella vita reale non avrai la media X_test quando prevedi un campione. Dovresti usare la media di X_train perché questi sono gli unici dati che hai effettivamente in mano (nel 99% degli scenari)
— Omri374

4

Non dimenticare

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

Che restituisce una maschera booleana che indica valori np.nan.

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

Che restituiscono le righe in cui è apparso np.nan. Quindi con una semplice indicizzazione puoi contrassegnare tutti i tuoi punti che sono np.nan.

df.loc[row_mask,col_mask]

3

Non dimenticare di controllare anche i valori inf. L'unica cosa che ha funzionato per me:

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

E ancora meglio se stai 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

Quando number_features sarebbe una matrice delle etichette number_features, ad esempio:

number_features = ['median_income', 'gdp']

2

Ho affrontato un problema simile e ho visto che intorpidito gestisce NaN e Inf in modo diverso.
In caso di dati con Inf, provare questo:

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

Ciò fornirà una tupla di posizione dei luoghi in cui sono presenti i valori di NA.

Nel caso in cui i tuoi dati abbiano Nan, prova questo:

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

1

Nella maggior parte dei casi, liberarsi di valori infiniti e nulli risolve questo problema.

sbarazzarsi di valori infiniti.

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

sbarazzarsi di valori null nel modo desiderato, valore specifico come 999, media o creare la propria funzione per imputare i valori mancanti

df.fillna(999, inplace=True)

o

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


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.