Python pandas: как удалить значения nan и -inf

У меня есть следующий файл данных

           time       X    Y  X_t0     X_tp0  X_t1     X_tp1  X_t2     X_tp2
0         0.002876    0   10     0       NaN   NaN       NaN   NaN       NaN
1         0.002986    0   10     0       NaN     0       NaN   NaN       NaN
2         0.037367    1   10     1  1.000000     0       NaN     0       NaN
3         0.037374    2   10     2  0.500000     1  1.000000     0       NaN
4         0.037389    3   10     3  0.333333     2  0.500000     1  1.000000
5         0.037393    4   10     4  0.250000     3  0.333333     2  0.500000

....
1030308   9.962213  256  268   256  0.000000   256  0.003906   255  0.003922
1030309  10.041799    0  268     0      -inf   256  0.000000   256  0.003906
1030310  10.118960    0  268     0       NaN     0      -inf   256  0.000000

Я попробовал следующее

df.dropna(inplace=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.40)

X_train = X_train.drop('time', axis=1)
X_train = X_train.drop('X_t1', axis=1)
X_train = X_train.drop('X_t2', axis=1)
X_test = X_test.drop('time', axis=1)
X_test = X_test.drop('X_t1', axis=1)
X_test = X_test.drop('X_t2', axis=1)
X_test.fillna(X_test.mean(), inplace=True)
X_train.fillna(X_train.mean(), inplace=True)
y_train.fillna(y_train.mean(), inplace=True)

Тем не менее, я все еще получаю эту ошибку ValueError: Input contains NaN, infinity or a value too large for dtype('float32'). всякий раз, когда я пытаюсь установить модель регрессии fit(X_train, y_train)

Как мы можем одновременно удалить значения NaN и -inf?

Ответ 1

Используйте pd.DataFrame.isin и проверьте наличие строк с pd.DataFrame.any. Наконец, используйте булевский массив для срезания фрейма данных.

df[~df.isin([np.nan, np.inf, -np.inf]).any(1)]

             time    X    Y  X_t0     X_tp0   X_t1     X_tp1   X_t2     X_tp2
4        0.037389    3   10     3  0.333333    2.0  0.500000    1.0  1.000000
5        0.037393    4   10     4  0.250000    3.0  0.333333    2.0  0.500000
1030308  9.962213  256  268   256  0.000000  256.0  0.003906  255.0  0.003922

Ответ 2

Вы можете заменить inf и -inf на NaN, а затем выбрать ненулевые строки.

df[df.replace([np.inf, -np.inf], np.nan).notnull().all(axis=1)]  # .astype(np.float64) ?

или

df.replace([np.inf, -np.inf], np.nan).dropna(axis=1)

Проверьте тип возвращаемых столбцов, чтобы убедиться, что они все как ожидалось (например, np.float32/64) через df.info().

Ответ 3

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

df.dropna(inplace=True)

Ответ 4

Вместо отбрасывания строк, которые содержат какие-либо нули и бесконечные числа, более кратким является обратная логика и вместо этого возвращаются строки, в которых все ячейки являются конечными числами. Это делает функция numpy isfinite, и '.all(1)' вернет TRUE, только если все ячейки в строке конечны.

df = df[np.isfinite(df).all(1)]