web-dev-qa-db-fra.com

Pandas Python: comment supprimer les valeurs nan et -inf

J'ai le dataframe suivant

           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

J'ai essayé avec ce qui suit

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)

Cependant, je reçois toujours cette erreur ValueError: Input contains NaN, infinity or a value too large for dtype('float32'). à chaque fois que j'essaie d'adapter un modèle de régression fit(X_train, y_train)

Comment pouvons-nous supprimer les valeurs NaN et -inf en même temps? 

12
user2154227

Utilisez pd.DataFrame.isin et recherchez les lignes avec pd.DataFrame.any. Enfin, utilisez le tableau booléen pour découper la trame de données.

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
19
piRSquared

Vous pouvez remplacer inf et -inf par NaN, puis sélectionner des lignes non nulles.

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

ou

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

Vérifiez le type de vos retours de colonne pour vous assurer qu'ils sont tous comme prévu (par exemple, np.float32/64) via df.info().

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

df.dropna(inplace=True)
1

Au lieu de supprimer des lignes contenant des valeurs nulles et des nombres infinis, il est plus succinct d’inverser la logique et de renvoyer les lignes où toutes les cellules sont des nombres finis. La fonction numpy isfinite remplit cette fonction et le paramètre '.all (1)' ne renvoie TRUE que si all les cellules de la ligne sont finies.

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