ValueError: Входные данные содержат NaN, бесконечность или значение, слишком большое для dtype ('float32')

42

Я получил ValueError при прогнозировании тестовых данных с использованием модели RandomForest.

Мой код:

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)

Ошибка:

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

Как найти неверные значения в тестовом наборе данных? Кроме того, я не хочу отбрасывать эти записи, могу ли я просто заменить их средним или медианным?

Спасибо.

Edamame
источник

Ответы:

45

С np.isnan(X)вами вы получите логическую маску обратно с True для позиций, содержащих NaNs.

С np.where(np.isnan(X))тобой вернемся кортеж с i, j координатами NaNs.

Наконец, с np.nan_to_num(X)вами «замените nan с нулем, а inf с конечными числами».

В качестве альтернативы вы можете использовать:

  • sklearn.impute.SimpleImputer для среднего / медианного вменения пропущенных значений, или
  • pandas ' pd.DataFrame(X).fillna(), если вам нужно что-то кроме заполнения нулями.
Фернанду
источник
Я предпочитаю условие идентификации для проверки nan, если x! = X вернет None, много раз np.isnan (x) потерпел неудачу для меня, не помню причину
Итачи
1
Не рекомендуется заменять значения NaN нулями. Значения NaN могут все еще иметь значение, так как их пропущение и приписывание их нулям, вероятно, является худшей вещью, которую вы можете сделать, и худшим методом вменения, который вы используете. Вы не только будете произвольно вводить нули, которые могут искажать вашу переменную, но 0 может даже не быть приемлемым значением в ваших переменных, то есть ваша переменная может не иметь истинного нуля.
Hussam
Я понял, что я не дал никаких указаний. Если вы хотите вменять свои данные, либо используйте скользящее среднее с помощью .rolling()замены отсутствующего значения на среднее значение скользящего окна. Если вы хотите что-то более надежное, используйте модуль <b> missingpy </ b>, который вы можете использовать MissForestдля вменения на основе случайного леса.
Hussam
7

Предполагая, X_testчто это pandas dataframe, вы можете использовать DataFrame.fillnaдля замены значений NaN на среднее:

X_test.fillna(X_test.mean())
kmandov
источник
X_test является массивом NumPy. Только что обновил df_test в исходном вопросе, все еще получил ту же ошибку ...
Edamame
7

Для любого, кто сталкивается с этим, чтобы на самом деле изменить оригинал:

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

Чтобы перезаписать оригинал:

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

Чтобы проверить, находитесь ли вы в копии против вида:

X_test._is_view
CommonSurname
источник
2
Хотя это технически верно, но практически неверно. Вы не можете заполнить X_test NA средним значением X_test, потому что в реальной жизни у вас не будет среднего значения X_test, когда вы прогнозируете выборку. Вы должны использовать среднее значение X_train, потому что это единственные данные, которые у вас есть (в 99% случаев),
Omri374
4

Не забывай

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

Который возвращает логическую маску, указывающую значения np.nan.

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

Которые возвращают строки, где появился np.nan. Затем с помощью простой индексации вы можете пометить все ваши точки, которые являются np.nan.

df.loc[row_mask,col_mask]
BMC
источник
3

Не забудьте также проверить значения inf. Единственное, что сработало для меня:

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

И даже лучше, если вы используете 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

Когда number_features будет массивом меток number_features, например:

number_features = ['median_income', 'gdp']
Kohn1001
источник
2

Я столкнулся с подобной проблемой и увидел, что numy обрабатывает NaN и Inf по-разному.
Если у вас есть данные Inf, попробуйте это:

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

Это даст кортеж мест, где присутствуют значения NA.

Если ваши данные содержат Nan, попробуйте это:

np.isnan(x.values.any())
Пракаш Ванапалли
источник
1

В большинстве случаев избавление от бесконечных и нулевых значений решает эту проблему.

избавиться от бесконечных ценностей.

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

избавьтесь от нулевых значений так, как вам нравится, от конкретного значения, такого как 999, до среднего или создайте свою собственную функцию для вменения пропущенных значений

df.fillna(999, inplace=True)

или

df.fillna(df.mean(), inplace=True)
Natheer Alabsi
источник
1

Если ваши значения больше чем float32, попробуйте сначала запустить какой-нибудь скейлер . Было бы довольно необычно иметь отклонение, охватывающее более чем float32.

Петр Рарус - Восстановить Монику
источник