ValueError: Dane wejściowe zawierają NaN, nieskończoność lub wartość zbyt dużą dla dtype („float32”)

41

Dostałem ValueError podczas przewidywania danych testowych przy użyciu modelu RandomForest.

Mój kod:

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)

Błąd:

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

Jak znaleźć złe wartości w zestawie danych testowych? Ponadto nie chcę upuszczać tych rekordów, czy mogę je po prostu zastąpić średnią lub medianą?

Dzięki.

Edamame
źródło

Odpowiedzi:

45

Po np.isnan(X)odzyskaniu maski logicznej z wartością True dla pozycji zawierających NaNs.

Gdy np.where(np.isnan(X))wrócisz krotkę ze współrzędnymi NaNs , j .

Wreszcie, z np.nan_to_num(X)tobą „zamień nan na zero i inf na skończone liczby”.

Alternatywnie możesz użyć:

  • sklearn.impute.SimpleImputer dla średniej / mediany imputacji brakujących wartości, lub
  • pandy ” pd.DataFrame(X).fillna(), jeśli potrzebujesz czegoś innego niż wypełnienie go zerami.
Fernando
źródło
Wolę warunek tożsamości do sprawdzania nan, jeśli x! = X return Brak, wiele razy np. Isnan (x) zawiodło dla mnie, nie pamiętam powodu
Itachi
1
Nie zaleca się zastępowania wartości NaN zerami. Brakuje wartości NaN, a przypisywanie im zer jest prawdopodobnie najgorszą rzeczą, jaką możesz zrobić, i najgorszą metodą imputacji. Nie tylko wprowadzisz zera arbitralnie, które mogą wypaczać zmienną, ale 0 może nawet nie być dopuszczalną wartością w zmiennych, co oznacza, że ​​twoja zmienna może nie mieć prawdziwego zera.
hussam
Uświadomiłem sobie, że nie zapewniłem żadnych wskazówek. Jeśli chcesz przypisać swoje dane albo użyj średniej kroczącej, używając, .rolling()aby zastąpić brakującą wartość średnią wartością kroczącego okna. Jeśli chcesz czegoś bardziej niezawodnego, użyj modułu <b> missingpy </b>, możesz użyć MissForestdo przypisania losowego opartego na lasach.
hussam
7

Zakładając, że X_testjest ramką danych pand, możesz użyć, DataFrame.fillnaaby zastąpić wartości NaN średnią:

X_test.fillna(X_test.mean())
kmandov
źródło
X_test to tablica numpy. Właśnie zaktualizowałem test df_test w pierwotnym pytaniu, wciąż
pojawia
6

Aby każdy mógł się z tym spotkać, aby faktycznie zmodyfikować oryginał:

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

Aby zastąpić oryginał:

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

Aby sprawdzić, czy jesteś w kopii czy w widoku:

X_test._is_view
Imię i nazwisko
źródło
2
Chociaż technicznie jest to prawdą, jest praktycznie błędne. Nie można wypełnić NA testami X środkiem X_test, ponieważ w prawdziwym życiu nie będziesz miał testu X_test, kiedy przewidujesz próbkę. Powinieneś użyć średniej X_train, ponieważ są to jedyne dane, które faktycznie masz pod ręką (w 99% scenariuszy)
Omri374
4

Nie zapomnij

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

Która zwraca maskę logiczną wskazującą np. Wartości.

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

Które zwracają wiersze, w których pojawił się np.nan. Następnie przez proste indeksowanie możesz oflagować wszystkie swoje punkty, np. Nan.

df.loc[row_mask,col_mask]
bmc
źródło
2

Napotkałem podobny problem i widziałem, że numpy obsługuje NaN i Inf inaczej.
Incase, jeśli twoje dane mają Inf, spróbuj tego:

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

To da krotkę lokalizacji miejsc, w których obecne są wartości NA.

Podaj, jeśli twoje dane mają Nan, spróbuj tego:

np.isnan(x.values.any())
Prakash Vanapalli
źródło
2

Nie zapomnij również sprawdzić wartości inf. Jedyne, co dla mnie zadziałało:

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

A nawet lepiej, jeśli używasz 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

Gdy liczba_funkcji będzie tablicą etykiet liczby_funkcji, na przykład:

number_features = ['median_income', 'gdp']
Kohn1001
źródło