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


41

Я отримав 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').

Як знайти погані значення в тестовому наборі даних? Крім того, я не хочу скидати ці записи, чи можу я просто замінити їх середнім чи середнім?

Дякую.

Відповіді:


45

З np.isnan(X)вами повернеться булева маска з істинним для позицій, що містять NaNs.

З np.where(np.isnan(X))вами повертається кортеж з i, j координатами NaNs.

Нарешті, з np.nan_to_num(X)вами "замініть нан на нуль, а інф - на кінцеві числа".

Крім того, ви можете використовувати:

  • sklearn.impute.SimpleImputer для середньої / середньої імпутації відсутніх значень, або
  • панди ' pd.DataFrame(X).fillna(), якщо вам потрібно щось інше, ніж заповнення нулів.

Я віддаю перевагу умові посвідчення для перевірки nan, якщо x! = X return Ні, багато разів np.isnan (x) не зміг мене, не пам'ятаю причину
Itachi

1
Не бажано замінювати значення NaN нулями. Значення NaN все ще можуть мати значення у відсутності, а імпультування їх нулями - це, мабуть, найгірше, що ви можете зробити, і найгірший метод імпутації, який ви використовуєте. Ви не тільки будете вводити нулі довільно, що може перекосити вашу змінну, але 0 може навіть не бути прийнятним значенням у ваших змінних, тобто ваша змінна може не мати справжнього нуля.
хусам

Я зрозумів, що ніяких вказівок не дав. Якщо ви хочете ввести свої дані, будь-ласка, використовуйте ковзаюче середнє значення, .rolling()щоб замінити пропущене значення середнім значенням вікна, що переходить. Якщо ви хочете щось більш надійне використовувати модуль <b> missingpy </b>, ви можете використовувати MissForestдля імпутації на основі випадкових лісів.
хусам

7

Якщо припустити X_test, що це фрейм даних панди, ви можете використовувати DataFrame.fillnaдля заміни значень NaN середнім:

X_test.fillna(X_test.mean())

X_test - це масивний масив. Щойно оновив df_test в оригінальному запитанні, все-таки отримав ту саму помилку ...
Edamame

6

Для всіх, хто трапляється через це, фактично змінювати оригінал:

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

Щоб перезаписати оригінал:

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

Щоб перевірити, чи є у вас копія та перегляд:

X_test._is_view

2
Хоча це правда технічно, це практично неправильно. Ви не можете заповнити найменування X_test середнім значенням 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]

2

Я зіткнувся з подібною проблемою і побачив, що онімі по-різному обробляє NaN та Inf.
У випадку, якщо у вас є інформація, спробуйте:

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

Це призведе до визначення місця розташування місць, де є значення NA.

Якщо у ваших даних є Nan, спробуйте:

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

2

Не забудьте перевірити також наявність значень 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']

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.